1. What is Reflection in Java?
2.Use of Reflection.
3. Where is Reflection API used?
4.Drawbacks of Reflection in Java.
5.Reflection API in Java.
6.Reflection Example code.
1. In Java, we can inspect a class and get information about the fields, methods, constructors, and implemented interfaces, superclasses at runtime.
2. We can even access the private field and invoke a private method from another class.
1. The Eclipse IDE can be seen using this API where with the use of command or interface we can see the list of methods in a class,auto-completing the fields or method name.
2. The persistence framework matching the fields in the objects with the fields in the database table at runtime.
3. Junits getting information about methods to be invoked.
4. Spring framework getting class information using the bean definition and also for dependency injection using setter and getter or constructor of the class. So here reflection is completely used for dependency injection.
1. Performance overhead.
2. Security Restrictions
3. Against Object Oriented principles
1. Class(java.lang.class):
This belongs to java.lang or default package, For any type of object, JVM instantiates an immutable instance of java.lang.Class which provides the method to examine the runtime properties including members and type information of the class. The class also provides the ability to create new classes and
objects. It is the entry point for all reflection API. Class is not part of reflection API it belongs to java.lang package.
2. Member(java.lang.reflect.Member):
This is an interface that belongs to the java.lang.reflect package which is implemented by Field, Method, and Constructor which also belongs to the same package which can be used to get information about class members.
It contains below methods:
-> Class<?> getDeclaringClass();
-> String getName();
-> int getModifiers();
3. Field(java.lang.Reflect.Field):
This class is present in java.lang.Reflect package, It provides methods for accessing type information about setting and getting of values of a field on a given object.
4. Method(java.lang.Reflect.Method):
This class is present in java.lang.Reflect package. It provides information about, and access to, a single method on a class or interface.
5. Constructor(java.lang.Reflect.Constructor) : It provides information about, and access to, a single constructor for a class.If we invoke constructor it will create a new instance of a class.
6. Array(java.lang.Reflect.Array) :
This class provides static methods to dynamically create and access Java arrays.
Class: HomeProduct
package com.amitclive.model; @Deprecated public class HomeProduct extends Product implements ProductInfo{ private int size; public HomeProduct(String name, Integer price, int size) { super(name, price); this.size = size; } @Override public void showSize() { System.out.println("showSize" +size); } }
Class: Product
package com.amitclive.model; public class Product { private String name; private Integer price; public Product(String name, Integer price) { this.name = name; this.price = price; } private Product() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } }
Interface: ProductInfo
package com.amitclive.model; public interface ProductInfo { void showSize(); }
Class: ReflectionMetadata
package com.amitclive.client; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; public class ReflectionMetadata { public static void main(String[] args) { // To get the classname try { Class<?> c1 = Class.forName("com.amitclive.model.HomeProduct"); System.out.println("classname : " + c1.getName()); System.out.println("classname : " + c1.getSimpleName()); } catch (ClassNotFoundException e) { e.printStackTrace(); } // To get the superclass try { Class<?> c1 = Class.forName("com.amitclive.model.HomeProduct"); System.out.println("super classname : " + c1.getSuperclass()); } catch (ClassNotFoundException e) { e.printStackTrace(); } // Getting implemented and extended interfaces using reflection try { Class<?> c1 = Class.forName("com.amitclive.model.HomeProduct"); System.out.println("interfaces : " + Arrays.toString(c1.getInterfaces())); } catch (ClassNotFoundException e) { e.printStackTrace(); } // Getting class modifier using reflection try { Class<?> c1 = Class.forName("com.amitclive.model.HomeProduct"); int modifiers = c1.getModifiers(); System.out.println("Modifers : " + Modifier.toString(modifiers)); } catch (ClassNotFoundException e) { e.printStackTrace(); } // Get fields of the class try { Class<?> c1 = Class.forName("com.amitclive.model.HomeProduct"); Field[] field = c1.getFields(); System.out.println("Fields : " + Arrays.toString(field)); Field[] fieldDeclared = c1.getDeclaredFields(); System.out.println("Fields : " + Arrays.toString(fieldDeclared)); } catch (ClassNotFoundException e) { e.printStackTrace(); } // Get constructors of the class try { Class<?> c1 = Class.forName("com.amitclive.model.HomeProduct"); Constructor[] construct = c1.getConstructors(); System.out.println("Constructor : " + Arrays.toString(construct)); Constructor[] constructDecalred = c1.getDeclaredConstructors(); System.out.println("Constructor : " + Arrays.toString(constructDecalred)); } catch (ClassNotFoundException e) { e.printStackTrace(); } // Get Methods of the class using reflection try { Class<?> c1 = Class.forName("com.amitclive.model.HomeProduct"); Method[] method = c1.getMethods(); System.out.println("Method : " + Arrays.toString(method)); Method[] methodDecalred = c1.getDeclaredMethods(); System.out.println("Method : " + Arrays.toString(methodDecalred)); } catch (ClassNotFoundException e) { e.printStackTrace(); } // Get Annotations of the class using reflection try { Class<?> c1 = Class.forName("com.amitclive.model.HomeProduct"); Annotation[] annotations = c1.getAnnotations(); System.out.println("Annotation : " + Arrays.toString(annotations)); Annotation[] annotationsDeclared = c1.getDeclaredAnnotations(); System.out.println("Annotation : " + Arrays.toString(annotationsDeclared)); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
Class: Product
package com.amitclive.model; public class Product { private String name; private Integer price; public Product(String name, Integer price) { this.name = name; this.price = price; } private Product() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } }
Class: ReflectionTest
package com.amitclive.client; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; public class ReflectionTest { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException { Class<?> cls = Class.forName("com.amitclive.model.Product"); // Get Constructor of the class Constructor<?>[] construct = cls.getConstructors(); System.out.println("Get Constructor of the class ====="); System.out.println("" + Arrays.toString(construct)); // Get declared methods of the class Method[] declaredMethod = cls.getDeclaredMethods(); System.out.println("Get declared methods of the class ====="); System.out.println("" + Arrays.toString(declaredMethod)); // Get all methods including inherited of the class Method[] methods = cls.getMethods(); System.out.println("Get all methods including inherited of the class ====="); System.out.println("" + Arrays.toString(methods)); // Get fields of the class Field[] fields = cls.getDeclaredFields(); System.out.println("Get fields of the class ====="); System.out.println("" + Arrays.toString(fields)); } }
Class: Welcome
package com.amitclive.model; public class Welcome { private String message ="Welcome Back"; }
Class: ReflectionPrivateAccess
package com.amitclive.client; import java.lang.reflect.Field; import com.amitclive.model.Welcome; public class ReflectionPrivateAccess { public static void main(String[] args) { try { Class<?> cls = Class.forName("com.amitclive.model.Welcome"); Field field = cls.getDeclaredField("message"); field.setAccessible(true); Object object = field.get(new Welcome()); String result = (String) object; System.out.println(result); } catch (ClassNotFoundException | NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { e.printStackTrace(); } } }
java.lang.reflect.Constructor.newInstanace() and Class.newInstance().
It is preferable to go with the one provided by the Constructor class for the reasons explained here.
-> Class.newInstance() can only invoke the zero-argument constructor, while Constructor.newInstace() may invoke any constructor,
regardless the number of parameters.
-> Class.newInstance() requires the constructor be visible; Constructor.newInstance() can invoke private constructor also by setting accessibility
true.
->Class.newInstance() throws any exception thrown by the constructor whether it is checked or unchecked exception. Constructor.newInstance()
always wraps the thrown exception with an InvocationTargetException.
Class: Student
package com.amitclive.model; public class Student { private int name; private long[] phoneNumbers; public Student(int name, long[] phoneNumbers) { super(); this.name = name; this.phoneNumbers = phoneNumbers; } public int getName() { return name; } public void setName(int name) { this.name = name; } public long[] getPhoneNumbers() { return phoneNumbers; } public void setPhoneNumbers(long[] phoneNumbers) { this.phoneNumbers = phoneNumbers; } }
Class: IdentifyArray
package com.amitclive.client; import java.lang.reflect.Field; //To determine if the class member is of an array type public class IdentifyArray { public static void main(String[] args) { try { Class<?> cls = Class.forName("com.amitclive.model.Student"); Field[] field = cls.getDeclaredFields(); for (Field f : field) { Class<?> type = f.getType(); if (type.isArray()) { System.out.println("Array Found : " + f.getName()); } } } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
Class: Product
package com.amitclive.model; public class Product { private String name; private Integer price; public Product(String name, Integer price) { this.name = name; this.price = price; } private Product() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } }
Class: InstanceCreation
package com.amitclive.client; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; import com.amitclive.model.Product; public class InstanceCreation { public static void main(String[] args) { try { Class<?> cls = Class.forName("com.amitclive.model.Product"); Constructor<?>[] constructor = cls.getConstructors(); for (Constructor con : constructor) { System.out.println(con.getName()); Product prod; if (Modifier.toString(con.getModifiers()).equals("private")) { // set accessibility to true if its a private constructor con.setAccessible(true); prod = (Product) con.newInstance(); } else { prod = (Product) con.newInstance("consructortest", 200); } System.out.println(prod.getPrice()); } } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } } }
Amit is a software developer by profession. He is passionate about all the technologies which can be used to build an application like java related technologies and many more and loves to implement it his career or for knowledge purpose and share his experience with you all. To know more see the About me profile.