1 package cz.frantovo.příklady.reflexe;
3 import java.lang.reflect.Field;
4 import java.math.BigDecimal;
5 import java.math.RoundingMode;
6 import java.util.function.Consumer;
10 * @author Ing. František Kučera (frantovo.cz)
12 public class Reflexe {
14 private static final String NÁZEV_PROMĚNNÉ = "proměnná";
15 private static final int POČET_OPAKOVÁNÍ = 1000000;
16 private static final RoundingMode ZAOKROUHLOVÁNÍ = RoundingMode.UP;
17 private static final int PŘESNOST_PROCENT = 2;
19 private static void nastav(Object objekt, String proměnná, Object hodnota) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
20 Field f = objekt.getClass().getDeclaredField(proměnná);
21 f.setAccessible(true);
22 f.set(objekt, hodnota);
23 // TODO: můžeme odchytávat výjimky a vyhazovat vlastní výjimku případně běhovou
26 private static void testSetter(int početOpakování) {
27 NějakáTřída t = new NějakáTřída();
28 for (int i = 0; i < početOpakování; i++) {
33 private static void testPřímýPřístup(int početOpakování) {
34 NějakáTřída t = new NějakáTřída();
35 for (int i = 0; i < početOpakování; i++) {
36 t.veřejnáProměnná = i;
40 private static void testReflexe(int početOpakování) {
41 NějakáTřída t = new NějakáTřída();
43 for (int i = 0; i < početOpakování; i++) {
44 nastav(t, NÁZEV_PROMĚNNÉ, i);
46 } catch (Exception e) {
47 throw new RuntimeException("test se nezdařil", e);
51 private static void testReflexePřipravená(int početOpakování) {
52 NějakáTřída t = new NějakáTřída();
54 Field f = t.getClass().getDeclaredField(NÁZEV_PROMĚNNÉ);
55 f.setAccessible(true);
56 for (int i = 0; i < početOpakování; i++) {
59 } catch (Exception e) {
60 throw new RuntimeException("test se nezdařil", e);
64 private static String lpad(int početZnaků, Object text) {
65 return String.format("%1$" + početZnaků + "s", String.valueOf(text));
68 private static BigDecimal spočítejProcenta(long hodnota, long základ) {
69 BigDecimal h = BigDecimal.valueOf(hodnota);
70 BigDecimal z = BigDecimal.valueOf(základ);
71 return h.multiply(BigDecimal.valueOf(100)).divide(z, PŘESNOST_PROCENT, ZAOKROUHLOVÁNÍ);
74 private static Long testuj(String názevTestu, int početOpakování, Long časProPorovnání, Consumer<Integer> test) {
75 System.out.print("TEST: " + lpad(20, názevTestu) + ": ");
77 long začátek = System.currentTimeMillis();
78 test.accept(početOpakování);
79 long konec = System.currentTimeMillis();
80 long celkovýČas = konec - začátek;
81 BigDecimal relativníČas = časProPorovnání == null ? BigDecimal.valueOf(100).setScale(PŘESNOST_PROCENT) : spočítejProcenta(celkovýČas, časProPorovnání);
82 System.out.println("početOpakování = " + lpad(12, početOpakování) + " celkovýČas = " + lpad(8, celkovýČas) + " ms relativníČas = " + lpad(8, relativníČas) + " %");
84 } catch (Exception e) {
85 System.out.println("došlo k chybě");
91 public static void main(String[] args) {
92 long základníČas = testuj("přímý přístup", POČET_OPAKOVÁNÍ, null, Reflexe::testPřímýPřístup);
93 testuj("setter", POČET_OPAKOVÁNÍ, základníČas, Reflexe::testSetter);
94 testuj("reflexe", POČET_OPAKOVÁNÍ, základníČas, Reflexe::testReflexe);
95 testuj("reflexe připravená", POČET_OPAKOVÁNÍ, základníČas, Reflexe::testReflexePřipravená);