franta-hg@27: package cz.frantovo.příklady.reflexe; franta-hg@27: franta-hg@27: import java.lang.reflect.Field; franta-hg@27: import java.math.BigDecimal; franta-hg@27: import java.math.RoundingMode; franta-hg@27: import java.util.function.Consumer; franta-hg@27: franta-hg@27: /** franta-hg@27: * franta-hg@27: * @author Ing. František Kučera (frantovo.cz) franta-hg@27: */ franta-hg@27: public class Reflexe { franta-hg@27: franta-hg@27: private static final String NÁZEV_PROMĚNNÉ = "proměnná"; franta-hg@27: private static final int POČET_OPAKOVÁNÍ = 1000000; franta-hg@27: private static final RoundingMode ZAOKROUHLOVÁNÍ = RoundingMode.UP; franta-hg@27: private static final int PŘESNOST_PROCENT = 2; franta-hg@27: franta-hg@27: private static void nastav(Object objekt, String proměnná, Object hodnota) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { franta-hg@27: Field f = objekt.getClass().getDeclaredField(proměnná); franta-hg@27: f.setAccessible(true); franta-hg@27: f.set(objekt, hodnota); franta-hg@27: // TODO: můžeme odchytávat výjimky a vyhazovat vlastní výjimku případně běhovou franta-hg@27: } franta-hg@27: franta-hg@27: private static void testSetter(int početOpakování) { franta-hg@27: NějakáTřída t = new NějakáTřída(); franta-hg@27: for (int i = 0; i < početOpakování; i++) { franta-hg@27: t.setProměnná(i); franta-hg@27: } franta-hg@27: } franta-hg@27: franta-hg@27: private static void testPřímýPřístup(int početOpakování) { franta-hg@27: NějakáTřída t = new NějakáTřída(); franta-hg@27: for (int i = 0; i < početOpakování; i++) { franta-hg@27: t.veřejnáProměnná = i; franta-hg@27: } franta-hg@27: } franta-hg@27: franta-hg@27: private static void testReflexe(int početOpakování) { franta-hg@27: NějakáTřída t = new NějakáTřída(); franta-hg@27: try { franta-hg@27: for (int i = 0; i < početOpakování; i++) { franta-hg@27: nastav(t, NÁZEV_PROMĚNNÉ, i); franta-hg@27: } franta-hg@27: } catch (Exception e) { franta-hg@27: throw new RuntimeException("test se nezdařil", e); franta-hg@27: } franta-hg@27: } franta-hg@27: franta-hg@27: private static void testReflexePřipravená(int početOpakování) { franta-hg@27: NějakáTřída t = new NějakáTřída(); franta-hg@27: try { franta-hg@27: Field f = t.getClass().getDeclaredField(NÁZEV_PROMĚNNÉ); franta-hg@27: f.setAccessible(true); franta-hg@27: for (int i = 0; i < početOpakování; i++) { franta-hg@27: f.set(t, i); franta-hg@27: } franta-hg@27: } catch (Exception e) { franta-hg@27: throw new RuntimeException("test se nezdařil", e); franta-hg@27: } franta-hg@27: } franta-hg@27: franta-hg@27: private static String lpad(int početZnaků, Object text) { franta-hg@27: return String.format("%1$" + početZnaků + "s", String.valueOf(text)); franta-hg@27: } franta-hg@27: franta-hg@27: private static BigDecimal spočítejProcenta(long hodnota, long základ) { franta-hg@27: BigDecimal h = BigDecimal.valueOf(hodnota); franta-hg@27: BigDecimal z = BigDecimal.valueOf(základ); franta-hg@27: return h.multiply(BigDecimal.valueOf(100)).divide(z, PŘESNOST_PROCENT, ZAOKROUHLOVÁNÍ); franta-hg@27: } franta-hg@27: franta-hg@27: private static Long testuj(String názevTestu, int početOpakování, Long časProPorovnání, Consumer test) { franta-hg@27: System.out.print("TEST: " + lpad(20, názevTestu) + ": "); franta-hg@27: try { franta-hg@27: long začátek = System.currentTimeMillis(); franta-hg@27: test.accept(početOpakování); franta-hg@27: long konec = System.currentTimeMillis(); franta-hg@27: long celkovýČas = konec - začátek; franta-hg@27: BigDecimal relativníČas = časProPorovnání == null ? BigDecimal.valueOf(100).setScale(PŘESNOST_PROCENT) : spočítejProcenta(celkovýČas, časProPorovnání); franta-hg@27: System.out.println("početOpakování = " + lpad(12, početOpakování) + " celkovýČas = " + lpad(8, celkovýČas) + " ms relativníČas = " + lpad(8, relativníČas) + " %"); franta-hg@27: return celkovýČas; franta-hg@27: } catch (Exception e) { franta-hg@27: System.out.println("došlo k chybě"); franta-hg@27: e.printStackTrace(); franta-hg@27: return null; franta-hg@27: } franta-hg@27: } franta-hg@27: franta-hg@27: public static void main(String[] args) { franta-hg@27: long základníČas = testuj("přímý přístup", POČET_OPAKOVÁNÍ, null, Reflexe::testPřímýPřístup); franta-hg@27: testuj("setter", POČET_OPAKOVÁNÍ, základníČas, Reflexe::testSetter); franta-hg@27: testuj("reflexe", POČET_OPAKOVÁNÍ, základníČas, Reflexe::testReflexe); franta-hg@27: testuj("reflexe připravená", POČET_OPAKOVÁNÍ, základníČas, Reflexe::testReflexePřipravená); franta-hg@27: } franta-hg@27: franta-hg@27: }