Table of contents
The 4 important classes of reflection
Class diagram of the Class class
Class objects of basic data types and Class objects of wrapper classes
what reflection can do
- Control the program through the configuration file without modifying the source code
- When the program is running, the object is dynamically created through reflection, and all properties, methods, and constructors of the object can be manipulated
- Generate dynamic proxy
The 4 important classes of reflection
- java.lang.Class
- java.lang.reflect.Field
- java.lang.reflect.Method
- java.lang.reflect.Constructor
class class
- A class has only one Class object in the heap, and this Class object contains the complete structural information of the class
- In the process of using reflection, methods, properties, and constructors are all treated as objects
- Class objects are created by the system and inherit the Object class
Class diagram of the Class class
Class common methods
//1.通过全路径 获取对应的Class对象
String classAllPath = "com.java.test.Student";
Class<?> cls = Class.forName(classAllPath);
//2.获取包名
String packageName = cls.getPackage().getName();
//3.获取全类名
String classFullName = cls.getName();
//4.通过Class对象创建对应对象的实例
Object obj = cls.newInstance();
//5.获取public修饰的属性,并设置值
Field nameField = cls.getField("name");
String nameValue = nameField.get(obj).toString();
nameField.set(obj,"jack");
System.out.println(nameField.get(obj)); //jack
//6.获取所有public修饰的属性(字段)
Field[] fields = cls.getFields();
for (Field field : fields) {
System.out.println(field.getName());
}
//7.获取所有属性,包括私有属性
Field[] declaredFields = cls.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField.getName());
}
4 ways to get Class objects
- Class.forName( )
- classname.class
- ObjectName.getClass( )
- The class loader gets the Class object
//1.通过Class类的静态方法forName()获取
String classAllPath = "com.java.test.Student";
Class<?> cls = Class.forName(classAllPath);
//2.类名.class
Class<String> stringClass = String.class;
//3.对象名.getClass():通过已经创建好的对象,获取Class对象
String str = new String("hello");
Class<? extends String> aClass = str.getClass();
//4.通过类加载器来获取类的Class对象
ClassLoader classLoader = str.getClass().getClassLoader();
//ClassLoader classLoader = String.class.getClassLoader();
Class<?> strClassObject = classLoader.loadClass("java.lang.String");
Class objects of basic data types and Class objects of wrapper classes
//byte short int long float double char boolean
Class<Byte> byteClass = byte.class;
Class<Short> shortClass = short.class;
Class<Integer> integerClass = int.class;
Class<Long> longClass = long.class;
Class<Float> floatClass = float.class;
Class<Double> doubleClass = double.class;
Class<Character> characterClass = char.class;
Class<Boolean> booleanClass = boolean.class;
Class<Integer> type = Integer.TYPE;
//其它包装类获取Class类对象的方式和Integer一样
Field class
- getField( )、getFields( )、getDeclaredFields( )
- getModifiers( ): returns modifiers
- getType( ): return type
- getName( ): returns the attribute name
//通过全路径 获取对应的Class对象
String classAllPath = "com.java.test.Student";
Class<?> cls = Class.forName(classAllPath);
//获取所有属性对象,包括私有属性
Field[] declaredFields = cls.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField.getModifiers()+" "+
declaredField.getType()+" "+declaredField.getName());
}
Method class
- getMethod( )、getMethods( )、getDeclaredMethods( )
- getModifiers( ): returns the return value type of the method
- getParameterTypes( ): returns an array of parameter types
- getName( ): returns the name of the method
//通过全路径 获取对应的Class对象
String classAllPath = "com.java.test.Student";
Class<?> cls = Class.forName(classAllPath);
获取所有方法对象,包括私有方法
Method[] declaredMethods = cls.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod.getModifiers()+" "+declaredMethod.getReturnType()+" "+
Arrays.toString(declaredMethod.getParameterTypes()));
}
Constructor class
- getConstructor( )、getConstructors( )、getDeclaredConstructors( )
- getModifiers( ): Returns the modifiers as an int
- getName( ): returns the full class name of the constructor
- getParameterTypes( ): returns an array of parameter types
- setAccessible( ): blasting, accessing private members
- newInstance( ): create an object
//通过全路径 获取对应的Class对象
String classAllPath = "com.java.test.Student";
Class<?> cls = Class.forName(classAllPath);
//获取所有的构造器对象,并且获取构造器对象的信息
Constructor<?>[] constructors = cls.getDeclaredConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor.getModifiers()+" "+constructor.getName()
+" "+Arrays.toString(constructor.getParameterTypes()));
}
// 使用反射创建对象
// 无参构造器创建对象
Object o = cls.newInstance();
// 有参构造器创建对象
Constructor<?> constructor = cls.getConstructor(int.class, String.class);
Object o2 = constructor.newInstance(1000, "hello");
// 私有有参构造器创建对象
Constructor<?> declaredConstructor = cls.getDeclaredConstructor(String.class);
declaredConstructor.setAccessible(true);
Object o3 = declaredConstructor.newInstance("jack");
Simple use of reflection
/** 需求:
1.根据配置文件的信息创建对象
2.通过反射操作private修饰的属性的值,并调用对象的方法
*/
propeties configuration file
classFullPath=com.java.reflection.Student
name=jack
method=sayHello
Student class
@Data
public class Student {
private String name;
public void sayHello(){
System.out.println("hello "+name);
}
}
main( ) method
public static void main(String[] args) throws Exception {
//1.使用Properties类读取Maven工程resources文件夹下的配置文件信息
//1.1读取配置文件到内存中
Properties properties = new Properties();
InputStream resourceAsStream = DemoTest.class.getResourceAsStream("/test.properties");
properties.load(resourceAsStream);
//1.2获取配置文件信息
String classFullPath = properties.get("classFullPath").toString();
String nameProValue = properties.get("name").toString();
String methodPro = properties.get("method").toString();
//2.使用反射机制创建对象,并调用对象的方法和属性
Class<?> cls = Class.forName(classFullPath); //获取运行时类对象
Object obj = cls.newInstance();//根据类对象创建对应的实例对象
Method methodObj = cls.getMethod(methodPro);//获取方法的对象
//获取属性的对象,并设置属性值
Field fieldObj = cls.getDeclaredField("name");
fieldObj.setAccessible(true);//私有属性必须先爆破,才能设置值
fieldObj.set(obj,nameProValue);
//通过方法对象调用方法
methodObj.invoke(obj);//hello jack
}