From db9dc5f286bae244ca4467f6443fee09df286c8c Mon Sep 17 00:00:00 2001 From: ovidiu-mihai98 <138307181+ovidiumihaitacu@users.noreply.github.com> Date: Sat, 30 Sep 2023 23:21:21 +0300 Subject: [PATCH] [BAEL-6794] Is Java Reflection Bad Practice? --- .../disadvantages/encapsulation/MyClass.java | 11 +++++ .../performance/BenchmarkRunner.java | 7 +++ .../performance/InitializationBenchmark.java | 29 +++++++++++ .../MethodInvocationBenchmark.java | 48 +++++++++++++++++++ .../disadvantages/performance/Person.java | 38 +++++++++++++++ .../ReflectionEncapsulationUnitTest.java | 21 ++++++++ 6 files changed, 154 insertions(+) create mode 100644 core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/encapsulation/MyClass.java create mode 100644 core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/performance/BenchmarkRunner.java create mode 100644 core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/performance/InitializationBenchmark.java create mode 100644 core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/performance/MethodInvocationBenchmark.java create mode 100644 core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/performance/Person.java create mode 100644 core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/disadvantages/encapsulation/ReflectionEncapsulationUnitTest.java diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/encapsulation/MyClass.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/encapsulation/MyClass.java new file mode 100644 index 0000000000..680079adea --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/encapsulation/MyClass.java @@ -0,0 +1,11 @@ +package com.baeldung.reflection.disadvantages.encapsulation; + +public class MyClass { + + private String veryPrivateField; + + public MyClass() { + + this.veryPrivateField = "Secret Information"; + } +} diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/performance/BenchmarkRunner.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/performance/BenchmarkRunner.java new file mode 100644 index 0000000000..1de026f796 --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/performance/BenchmarkRunner.java @@ -0,0 +1,7 @@ +package com.baeldung.reflection.disadvantages.performance; + +public class BenchmarkRunner { + public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(args); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/performance/InitializationBenchmark.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/performance/InitializationBenchmark.java new file mode 100644 index 0000000000..e6c0c3daea --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/performance/InitializationBenchmark.java @@ -0,0 +1,29 @@ +package com.baeldung.reflection.disadvantages.performance; + +import org.openjdk.jmh.annotations.*; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.TimeUnit; + +public class InitializationBenchmark { + + @Benchmark + @Fork(value = 1, warmups = 1) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + @BenchmarkMode(Mode.AverageTime) + public void directInit() { + + Person person = new Person("John", "Doe", 50); + } + + @Benchmark + @Fork(value = 1, warmups = 1) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + @BenchmarkMode(Mode.AverageTime) + public void reflectiveInit() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { + + Constructor constructor = Person.class.getDeclaredConstructor(String.class, String.class, Integer.class); + Person person = constructor.newInstance("John", "Doe", 50); + } +} diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/performance/MethodInvocationBenchmark.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/performance/MethodInvocationBenchmark.java new file mode 100644 index 0000000000..1128cf8f33 --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/performance/MethodInvocationBenchmark.java @@ -0,0 +1,48 @@ +package com.baeldung.reflection.disadvantages.performance; + +import org.openjdk.jmh.annotations.*; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.concurrent.TimeUnit; + +public class MethodInvocationBenchmark { + + @Benchmark + @Fork(value = 1, warmups = 1) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + @BenchmarkMode(Mode.AverageTime) + public void directCall() { + + directCall(new Person("John", "Doe", 50)); + } + + @Benchmark + @Fork(value = 1, warmups = 1) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + @BenchmarkMode(Mode.AverageTime) + public void reflectiveCall() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { + + reflectiveCall(new Person("John", "Doe", 50)); + } + + + private void directCall(Person person) { + + person.getFirstName(); + person.getLastName(); + person.getAge(); + } + + private void reflectiveCall(Person person) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + + Method getFirstNameMethod = Person.class.getMethod("getFirstName"); + getFirstNameMethod.invoke(person); + + Method getLastNameMethod = Person.class.getMethod("getLastName"); + getLastNameMethod.invoke(person); + + Method getAgeMethod = Person.class.getMethod("getAge"); + getAgeMethod.invoke(person); + } +} diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/performance/Person.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/performance/Person.java new file mode 100644 index 0000000000..014c82ba45 --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/disadvantages/performance/Person.java @@ -0,0 +1,38 @@ +package com.baeldung.reflection.disadvantages.performance; + +public class Person { + + private String firstName; + private String lastName; + private Integer age; + + public Person(String firstName, String lastName, Integer age) { + this.firstName = firstName; + this.lastName = lastName; + this.age = age; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } +} diff --git a/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/disadvantages/encapsulation/ReflectionEncapsulationUnitTest.java b/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/disadvantages/encapsulation/ReflectionEncapsulationUnitTest.java new file mode 100644 index 0000000000..efb0a7da31 --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/disadvantages/encapsulation/ReflectionEncapsulationUnitTest.java @@ -0,0 +1,21 @@ +package com.baeldung.reflection.disadvantages.encapsulation; + +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Field; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ReflectionEncapsulationUnitTest { + + @Test + public void givenPrivateField_whenUsingReflection_thenIsAccessible() throws IllegalAccessException, NoSuchFieldException { + MyClass myClassInstance = new MyClass(); + + Field privateField = MyClass.class.getDeclaredField("veryPrivateField"); + privateField.setAccessible(true); + + String accessedField = privateField.get(myClassInstance).toString(); + assertEquals(accessedField, "Secret Information"); + } +}