diff --git a/reflection/pom.xml b/reflection/pom.xml
new file mode 100644
index 0000000000..d3e5b16231
--- /dev/null
+++ b/reflection/pom.xml
@@ -0,0 +1,30 @@
+
+ 4.0.0
+ com.baeldung
+ reflection
+ 1.0
+ reflection
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.3
+
+
+ 7
+
+
+
+
+
+
+ junit
+ junit
+ 4.3
+ test
+
+
+
+
diff --git a/reflection/src/main/java/com/baeldung/reflection/Animal.java b/reflection/src/main/java/com/baeldung/reflection/Animal.java
new file mode 100644
index 0000000000..2370659d34
--- /dev/null
+++ b/reflection/src/main/java/com/baeldung/reflection/Animal.java
@@ -0,0 +1,26 @@
+package com.baeldung.reflection;
+
+public abstract class Animal implements Eating{
+ public static final String CATEGORY = "domestic";
+ private String name;
+
+ public Animal(String name) {
+ super();
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String makeSound() {
+ return getSound();
+ }
+
+ protected abstract String getSound();
+
+}
diff --git a/reflection/src/main/java/com/baeldung/reflection/Bird.java b/reflection/src/main/java/com/baeldung/reflection/Bird.java
new file mode 100644
index 0000000000..eb7115c53a
--- /dev/null
+++ b/reflection/src/main/java/com/baeldung/reflection/Bird.java
@@ -0,0 +1,33 @@
+package com.baeldung.reflection;
+
+public class Bird extends Animal {
+ private boolean walks;
+ public Bird() {
+ super("bird");
+ }
+ public Bird(String name, boolean walks) {
+ super(name);
+ setWalks(walks);
+ }
+ public Bird(String name) {
+ super(name);
+ }
+
+ @Override
+ public String eats() {
+ return "grains";
+ }
+
+ @Override
+ protected String getSound() {
+ return "chaps";
+ }
+
+ public boolean walks() {
+ return walks;
+ }
+
+ public void setWalks(boolean walks) {
+ this.walks = walks;
+ }
+}
diff --git a/reflection/src/main/java/com/baeldung/reflection/Eating.java b/reflection/src/main/java/com/baeldung/reflection/Eating.java
new file mode 100644
index 0000000000..4e73be0d52
--- /dev/null
+++ b/reflection/src/main/java/com/baeldung/reflection/Eating.java
@@ -0,0 +1,5 @@
+package com.baeldung.reflection;
+
+public interface Eating {
+ public String eats();
+}
diff --git a/reflection/src/main/java/com/baeldung/reflection/Goat.java b/reflection/src/main/java/com/baeldung/reflection/Goat.java
new file mode 100644
index 0000000000..9dc69f626b
--- /dev/null
+++ b/reflection/src/main/java/com/baeldung/reflection/Goat.java
@@ -0,0 +1,24 @@
+package com.baeldung.reflection;
+
+public class Goat extends Animal implements Locomotion{
+
+ public Goat(String name) {
+ super(name);
+ }
+
+ @Override
+ protected String getSound() {
+ return "bleat";
+ }
+
+ @Override
+ public String getLocomotion() {
+ return "walks";
+ }
+
+ @Override
+ public String eats() {
+ return "grass";
+ }
+
+}
diff --git a/reflection/src/main/java/com/baeldung/reflection/Locomotion.java b/reflection/src/main/java/com/baeldung/reflection/Locomotion.java
new file mode 100644
index 0000000000..4b1e54a4e9
--- /dev/null
+++ b/reflection/src/main/java/com/baeldung/reflection/Locomotion.java
@@ -0,0 +1,5 @@
+package com.baeldung.reflection;
+
+public interface Locomotion {
+ public String getLocomotion();
+}
diff --git a/reflection/src/main/java/com/baeldung/reflection/Person.java b/reflection/src/main/java/com/baeldung/reflection/Person.java
new file mode 100644
index 0000000000..66250f8da1
--- /dev/null
+++ b/reflection/src/main/java/com/baeldung/reflection/Person.java
@@ -0,0 +1,6 @@
+package com.baeldung.reflection;
+
+public class Person {
+ private String name;
+ private int age;
+}
diff --git a/reflection/src/test/java/com/baeldung/reflection/ReflectionTest.java b/reflection/src/test/java/com/baeldung/reflection/ReflectionTest.java
new file mode 100644
index 0000000000..7eb0c35671
--- /dev/null
+++ b/reflection/src/test/java/com/baeldung/reflection/ReflectionTest.java
@@ -0,0 +1,316 @@
+package com.baeldung.reflection;
+
+import static org.junit.Assert.*;
+
+import java.lang.reflect.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+
+public class ReflectionTest {
+ @Test
+ public void givenObject_whenGetsFieldNamesAtRuntime_thenCorrect() {
+ Object person = new Person();
+ Field[] fields = person.getClass().getDeclaredFields();
+ List expectedFieldNames = Arrays.asList(new String[] { "name",
+ "age" });
+
+ List actualFieldNames = new ArrayList<>();
+ for (Field field : fields)
+ actualFieldNames.add(field.getName());
+
+ assertTrue(expectedFieldNames.containsAll(actualFieldNames));
+
+ }
+
+ @Test
+ public void givenObject_whenGetsClassName_thenCorrect() {
+ Object goat = new Goat("goat");
+ Class> clazz = goat.getClass();
+ assertEquals("Goat", clazz.getSimpleName());
+ assertEquals("com.baeldung.reflection.Goat", clazz.getName());
+ assertEquals("com.baeldung.reflection.Goat", clazz.getCanonicalName());
+ }
+
+ @Test
+ public void givenClassName_whenCreatesObject_thenCorrect()
+ throws ClassNotFoundException {
+ Class> clazz = Class.forName("com.baeldung.reflection.Goat");
+ assertEquals("Goat", clazz.getSimpleName());
+ assertEquals("com.baeldung.reflection.Goat", clazz.getName());
+ assertEquals("com.baeldung.reflection.Goat", clazz.getCanonicalName());
+ }
+
+ @Test
+ public void givenClass_whenRecognisesModifiers_thenCorrect()
+ throws ClassNotFoundException {
+ Class> goatClass = Class.forName("com.baeldung.reflection.Goat");
+ Class> animalClass = Class.forName("com.baeldung.reflection.Animal");
+ int goatMods = goatClass.getModifiers();
+ int animalMods = animalClass.getModifiers();
+ assertTrue(Modifier.isPublic(goatMods));
+ assertTrue(Modifier.isAbstract(animalMods));
+ assertTrue(Modifier.isPublic(animalMods));
+ }
+
+ @Test
+ public void givenClass_whenGetsPackageInfo_thenCorrect() {
+ Goat goat = new Goat("goat");
+ Class> goatClass = goat.getClass();
+ Package pkg = goatClass.getPackage();
+ assertEquals("com.baeldung.reflection", pkg.getName());
+ }
+
+ @Test
+ public void givenClass_whenGetsSuperClass_thenCorrect() {
+ Goat goat = new Goat("goat");
+ String str = "any string";
+
+ Class> goatClass = goat.getClass();
+ Class> goatSuperClass = goatClass.getSuperclass();
+
+ assertEquals("Animal", goatSuperClass.getSimpleName());
+ assertEquals("Object", str.getClass().getSuperclass().getSimpleName());
+
+ }
+
+ @Test
+ public void givenClass_whenGetsImplementedInterfaces_thenCorrect()
+ throws ClassNotFoundException {
+ Class> goatClass = Class.forName("com.baeldung.reflection.Goat");
+ Class> animalClass = Class.forName("com.baeldung.reflection.Animal");
+ Class>[] goatInterfaces = goatClass.getInterfaces();
+ Class>[] animalInterfaces = animalClass.getInterfaces();
+ assertEquals(1, goatInterfaces.length);
+ assertEquals(1, animalInterfaces.length);
+ assertEquals("Locomotion", goatInterfaces[0].getSimpleName());
+ assertEquals("Eating", animalInterfaces[0].getSimpleName());
+ }
+
+ @Test
+ public void givenClass_whenGetsConstructor_thenCorrect()
+ throws ClassNotFoundException {
+ Class> goatClass = Class.forName("com.baeldung.reflection.Goat");
+ Constructor>[] constructors = goatClass.getConstructors();
+ assertEquals(1, constructors.length);
+ assertEquals("com.baeldung.reflection.Goat", constructors[0].getName());
+ }
+
+ @Test
+ public void givenClass_whenGetsFields_thenCorrect()
+ throws ClassNotFoundException {
+ Class> animalClass = Class.forName("com.baeldung.reflection.Animal");
+ Field[] fields = animalClass.getDeclaredFields();
+ List expectedFields = Arrays.asList(new String[] { "name",
+ "CATEGORY" });
+ List actualFields = new ArrayList<>();
+ for (Field field : fields)
+ actualFields.add(field.getName());
+ assertEquals(2, actualFields.size());
+ assertTrue(actualFields.containsAll(expectedFields));
+ }
+
+ @Test
+ public void givenClass_whenGetsMethods_thenCorrect()
+ throws ClassNotFoundException {
+ Class> animalClass = Class.forName("com.baeldung.reflection.Animal");
+ Method[] methods = animalClass.getDeclaredMethods();
+ List expectedMethods = Arrays.asList(new String[] { "getName",
+ "setName", "getSound", "makeSound" });
+ List actualMethods = new ArrayList<>();
+ for (Method method : methods)
+ actualMethods.add(method.getName());
+ assertEquals(4, actualMethods.size());
+ assertTrue(actualMethods.containsAll(expectedMethods));
+
+ }
+
+ @Test
+ public void givenClass_whenGetsAllConstructors_thenCorrect()
+ throws ClassNotFoundException {
+ Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ Constructor>[] constructors = birdClass.getConstructors();
+ assertEquals(3, constructors.length);
+ }
+
+ @Test
+ public void givenClass_whenGetsEachConstructorByParamTypes_thenCorrect()
+ throws ClassNotFoundException, NoSuchMethodException,
+ SecurityException {
+ Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ Constructor> cons1 = birdClass.getConstructor();
+ Constructor> cons2 = birdClass.getConstructor(String.class);
+ Constructor> cons3 = birdClass.getConstructor(String.class,
+ boolean.class);
+ }
+
+ @Test
+ public void givenClass_whenInstantiatesObjectsAtRuntime_thenCorrect()
+ throws ClassNotFoundException, NoSuchMethodException,
+ SecurityException, InstantiationException, IllegalAccessException,
+ IllegalArgumentException, InvocationTargetException {
+ Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ Constructor> cons1 = birdClass.getConstructor();
+ Constructor> cons2 = birdClass.getConstructor(String.class);
+ Constructor> cons3 = birdClass.getConstructor(String.class,
+ boolean.class);
+ Bird bird1 = (Bird) cons1.newInstance();
+ Bird bird2 = (Bird) cons2.newInstance("Weaver bird");
+ Bird bird3 = (Bird) cons3.newInstance("dove", true);
+ assertEquals("bird", bird1.getName());
+ assertEquals("Weaver bird", bird2.getName());
+ assertEquals("dove", bird3.getName());
+ assertFalse(bird1.walks());
+ assertTrue(bird3.walks());
+ }
+
+ @Test
+ public void givenClass_whenGetsPublicFields_thenCorrect()
+ throws ClassNotFoundException {
+ Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ Field[] fields = birdClass.getFields();
+ assertEquals(1, fields.length);
+ assertEquals("CATEGORY", fields[0].getName());
+
+ }
+
+ @Test
+ public void givenClass_whenGetsPublicFieldByName_thenCorrect()
+ throws ClassNotFoundException, NoSuchFieldException,
+ SecurityException {
+ Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ Field field = birdClass.getField("CATEGORY");
+ assertEquals("CATEGORY", field.getName());
+
+ }
+
+ @Test
+ public void givenClass_whenGetsDeclaredFields_thenCorrect()
+ throws ClassNotFoundException {
+ Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ Field[] fields = birdClass.getDeclaredFields();
+ assertEquals(1, fields.length);
+ assertEquals("walks", fields[0].getName());
+ }
+
+ @Test
+ public void givenClass_whenGetsFieldsByName_thenCorrect()
+ throws ClassNotFoundException, NoSuchFieldException,
+ SecurityException {
+ Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ Field field = birdClass.getDeclaredField("walks");
+ assertEquals("walks", field.getName());
+
+ }
+
+ @Test
+ public void givenClassField_whenGetsType_thenCorrect()
+ throws ClassNotFoundException, NoSuchFieldException,
+ SecurityException {
+ Field field = Class.forName("com.baeldung.reflection.Bird")
+ .getDeclaredField("walks");
+ Class> fieldClass = field.getType();
+ assertEquals("boolean", fieldClass.getSimpleName());
+ }
+
+ @Test
+ public void givenClassField_whenSetsAndGetsValue_thenCorrect()
+ throws ClassNotFoundException, NoSuchFieldException,
+ SecurityException, InstantiationException, IllegalAccessException {
+ Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ Bird bird = (Bird) birdClass.newInstance();
+ Field field = birdClass.getDeclaredField("walks");
+ field.setAccessible(true);
+
+ assertFalse(field.getBoolean(bird));
+ assertFalse(bird.walks());
+
+ field.set(bird, true);
+
+ assertTrue(field.getBoolean(bird));
+ assertTrue(bird.walks());
+
+ }
+
+ @Test
+ public void givenClassField_whenGetsAndSetsWithNull_thenCorrect()
+ throws ClassNotFoundException, InstantiationException,
+ IllegalAccessException, NoSuchFieldException, SecurityException {
+ Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ Field field = birdClass.getField("CATEGORY");
+ field.setAccessible(true);
+
+ assertEquals("domestic", field.get(null));
+ }
+
+ @Test
+ public void givenClass_whenGetsAllPublicMethods_thenCorrect()
+ throws ClassNotFoundException {
+ Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ Method[] methods = birdClass.getMethods();
+ List methodNames = new ArrayList<>();
+ for (Method method : methods)
+ methodNames.add(method.getName());
+ assertTrue(methodNames.containsAll(Arrays
+ .asList(new String[] { "equals", "notifyAll", "hashCode",
+ "walks", "eats", "toString" })));
+
+ }
+
+ @Test
+ public void givenClass_whenGetsOnlyDeclaredMethods_thenCorrect()
+ throws ClassNotFoundException {
+ Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ Method[] methods = birdClass.getDeclaredMethods();
+ List expectedMethodNames = Arrays.asList(new String[] {
+ "setWalks", "walks", "getSound", "eats" });
+ List actualMethodNames = new ArrayList<>();
+ for (Method method : methods)
+ actualMethodNames.add(method.getName());
+ assertEquals(expectedMethodNames.size(), actualMethodNames.size());
+ assertTrue(expectedMethodNames.containsAll(actualMethodNames));
+ assertTrue(actualMethodNames.containsAll(expectedMethodNames));
+
+ }
+
+ @Test
+ public void givenMethodName_whenGetsMethod_thenCorrect()
+ throws ClassNotFoundException, NoSuchMethodException,
+ SecurityException {
+ Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ Method walksMethod = birdClass.getDeclaredMethod("walks");
+ Method setWalksMethod = birdClass.getDeclaredMethod("setWalks",
+ boolean.class);
+ assertFalse(walksMethod.isAccessible());
+ assertFalse(setWalksMethod.isAccessible());
+ walksMethod.setAccessible(true);
+ setWalksMethod.setAccessible(true);
+ assertTrue(walksMethod.isAccessible());
+ assertTrue(setWalksMethod.isAccessible());
+
+ }
+
+ @Test
+ public void givenMethod_whenInvokes_thenCorrect()
+ throws ClassNotFoundException, NoSuchMethodException,
+ SecurityException, IllegalAccessException,
+ IllegalArgumentException, InvocationTargetException,
+ InstantiationException {
+ Class> birdClass = Class.forName("com.baeldung.reflection.Bird");
+ Bird bird = (Bird) birdClass.newInstance();
+ Method setWalksMethod = birdClass.getDeclaredMethod("setWalks",
+ boolean.class);
+ Method walksMethod = birdClass.getDeclaredMethod("walks");
+ boolean walks = (boolean) walksMethod.invoke(bird);
+ assertFalse(walks);
+ assertFalse(bird.walks());
+ setWalksMethod.invoke(bird, true);
+ boolean walks2 = (boolean) walksMethod.invoke(bird);
+ assertTrue(walks2);
+ assertTrue(bird.walks());
+
+ }
+
+}