Merge pull request #14949 from ovidiumihaitacu/master

[BAEL-6794] Is Java Reflection Bad Practice?
This commit is contained in:
Maiklins 2023-10-12 00:10:42 +02:00 committed by GitHub
commit b37081d8cf
9 changed files with 235 additions and 0 deletions

View File

@ -0,0 +1,2 @@
### Relevant Articles:
- [Is Java Reflection Bad Practice?](https://www.baeldung.com/java-reflection-bad-practice)

View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>core-java-reflection-3</artifactId>
<name>core-java-reflection-3</name>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung.core-java-modules</groupId>
<artifactId>core-java-modules</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>${reflections.version}</version>
</dependency>
</dependencies>
<build>
<finalName>core-java-reflection-3</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${source.version}</source>
<target>${target.version}</target>
<compilerArgument>-parameters</compilerArgument>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.8</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<reflections.version>0.9.12</reflections.version>
<source.version>1.8</source.version>
<target.version>1.8</target.version>
<spring.version>5.3.4</spring.version>
</properties>
</project>

View File

@ -0,0 +1,11 @@
package com.baeldung.reflection.disadvantages.encapsulation;
public class MyClass {
private String veryPrivateField;
public MyClass() {
this.veryPrivateField = "Secret Information";
}
}

View File

@ -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);
}
}

View File

@ -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<Person> constructor = Person.class.getDeclaredConstructor(String.class, String.class, Integer.class);
Person person = constructor.newInstance("John", "Doe", 50);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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");
}
}

View File

@ -158,6 +158,7 @@
<module>core-java-properties</module>
<module>core-java-reflection</module>
<module>core-java-reflection-2</module>
<module>core-java-reflection-3</module>
<module>core-java-scanner</module>
<module>core-java-security-2</module>
<module>core-java-security-3</module>