java反射基本使用
java反射基本使用
-
- 一. 反射的作用
- 二. 反射基本使用示例
- 三. 反射爆破
- 四. 反射相关类和对应方法介绍
-
- 1. Class
-
- (1) 常用方法
- (2) 使用示例
- 2. Field
-
- (1) 常用方法
- (2) 使用示例
- 3. Method
-
- (1) 常用方法
- (2) 使用示例
- 4. Constructor
-
- (1) 常用方法
- (2) 使用示例
- 有错误欢迎指出
一. 反射的作用
当程序中要定义一个不确定类型的类对象,就可以使用反射来创建类对象,因为反射只有在运行时才会被加载。
二. 反射基本使用示例
Dog类:
package com.reflect.example;public class Dog {public void bark() {System.out.println("小狗汪汪叫");}
}
Demo类:
package com.reflect.example;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class Demo {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {String classFullPath = "com.reflect.example.Dog";// 加载类Class classDog = Class.forName(classFullPath);// 创建类对象Object dog = classDog.newInstance();// 获取bark方法对象Method method = classDog.getDeclaredMethod("bark");// 调用方法method.invoke(dog);}
}
三. 反射爆破
private修饰的构造器、属性、方法是不允许被访问的,反射提供了一种爆破机制,可以强制访问private修饰的构造器、属性、方法。具体操作见 (四. 反射相关类和对应方法介绍)
四. 反射相关类和对应方法介绍
1. Class
Class类是反射的核心, 每个类都有唯一的一个Class类,Class类中保存了实际类中的成员属性、成员方法、构造方法、静态变量、静态方法。
(1) 常用方法
方法 | 作用 |
---|---|
getName() | 获取全类名(带有包名的类名) |
getSimpleName() | 获取类名 |
getFields() | 获取所有public修饰的属性,包括父类 |
getDeclaredFields() | 获取当前类所有属性 |
getField(String name) | 根据属性名获取public属性,包括父类属性 |
getDeclaredField(String name) | 根据属性名获取本类中任意权限修饰符修饰的属性 |
getMethods() | 获取所有public方法,包括父类 |
getDeclaredMethods() | 获取本类中所有方法 |
getMethod(String name) | 根据方法名获取public方法,包括父类 |
getDeclaredMethod(String name) | 根据方法名获取本类任意权限修饰符修饰的方法 |
getConstructors() | 获取本类所有public构造方法 |
getDeclaredConstructors() | 获取本类所有权限修饰符修饰的构造方法 |
getConstructor(Class<?>... parameterTypes) | 根据参数类型获取public构造方法 |
getDeclaredConstructor(Class<?>... parameterTypes) | 根据参数类型获取所有权限修饰符修饰的构造方法 |
(2) 使用示例
Father类:
package com.reflect.classexample;public class Father {public String name = "一个父亲";private int age = 30;public Father() {}public Father(String name, int age) {this.name = name;this.age = age;}public void duty() {System.out.println("赚钱养家");}private void attitude() {System.out.println("提升自己");}
}
Son类:
package com.reflect.classexample;public class Son extends Father{public int height = 20;private int weight = 7;public Son() {}public Son(String name, int age, int height, int weight) {super(name, age);this.height = height;this.weight = weight;}private Son(int height, int weight) {this.height = height;this.weight = weight;}public void learn() {System.out.println("好好学习");}private void grow() {System.out.println("健康成长,养成积极向上的世界观");}public void addElectiveCourse(String cource) {System.out.println("选修" + cource + "课程");}
}
Demo类:
package com.reflect.classexample;import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;public class Demo {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException {// 加载类Class classSon = Class.forName("com.reflect.classexample.Son");/**** 方法示例*/// 1. 获取全类名System.out.println("全类名: " + classSon.getName());System.out.println();// 2. 获取类名System.out.println("类名: " + classSon.getSimpleName());System.out.println();// 3. 获取所有public修饰的属性,包括父类Field[] fields = classSon.getFields();for (Field field : fields) {System.out.println("public属性: " + field);}System.out.println();// 4. 获取当前类所有属性Field[] fields2 = classSon.getDeclaredFields();for (Field field : fields2) {System.out.println("所有属性: " + field);}System.out.println();// 5. 根据属性名获取public属性,包括父类属性Field field = classSon.getField("height");System.out.println(field);Field field2 = classSon.getField("name");System.out.println(field2);System.out.println();// 6.根据属性名获取本类中任意权限修饰符修饰的属性Field field3 = classSon.getDeclaredField("weight");System.out.println(field3);System.out.println();// 7. 获取所有public方法,包括父类Method[] methods = classSon.getMethods();for (Method method : methods) {System.out.println("public方法:" + method);}System.out.println();// 8. 获取本类中所有方法Method[] methods2 = classSon.getDeclaredMethods();for (Method method : methods2) {System.out.println("本类中方法:" + method);}System.out.println();// 9. 根据方法名获取public方法,包括父类Method dutyMethod = classSon.getMethod("duty");System.out.println(dutyMethod);Method addElectiveCourceMethod = classSon.getMethod("addElectiveCourse", String.class);System.out.println(addElectiveCourceMethod);System.out.println();// 10. 根据方法名获取本类任意权限修饰符修饰的方法Method growMethod = classSon.getDeclaredMethod("grow");System.out.println(growMethod);Method learnMethod = classSon.getDeclaredMethod("learn");System.out.println(learnMethod);System.out.println();// 11. 获取本类所有public构造方法Constructor[] constructors = classSon.getConstructors();for (Constructor constructor : constructors) {System.out.println("public构造方法:" + constructor);}System.out.println();// 12. 获取本类所有权限修饰符修饰的构造方法Constructor[] declaredConstructors = classSon.getDeclaredConstructors();for (Constructor declaredConstructor : declaredConstructors) {System.out.println("所有构造方法:" + declaredConstructor);}System.out.println();// 13. 根据参数类型获取public构造方法Constructor constructor = classSon.getConstructor();System.out.println("public构造方法:" + constructor);Constructor constructor2 = classSon.getConstructor(String.class, int.class, int.class, int.class);System.out.println("public构造方法:" + constructor2);System.out.println();//14. 根据参数类型获取所有权限修饰符修饰的构造方法Constructor declaredConstructor = classSon.getDeclaredConstructor(int.class, int.class);System.out.println("所有权限修饰符修饰的构造方法:" + declaredConstructor);Constructor declaredConstructor2 = classSon.getDeclaredConstructor();System.out.println("所有权限修饰符修饰的构造方法:" + declaredConstructor2);System.out.println();}
}
2. Field
(1) 常用方法
方法 | 作用 |
---|---|
get(Object obj) | 获取obj对象的属性值,静态属性obj可以为nul |
set(Object obj, Object value) | 为obj对象属性赋值为value,静态属性obj可以为null |
setAccessible(booleab flag) | 设置是否允许访问private属性,true表示允许,false表示不允许 |
getType() | 获取属性类型 |
(2) 使用示例
Person类:
package com.reflect.fieldexample;public class Person {public int numOfEye = 2;private double money = 1;public Person() {}public Person(int numOfEye, double money) {this.numOfEye = numOfEye;this.money = money;}
}
AsianPerson类:
package com.reflect.fieldexample;public class AsianPerson extends Person{private float height = 170;public float weight = 134;private static int IQ = 200;public AsianPerson() {}public AsianPerson(int numOfEye, double money, float height, float weight) {super(numOfEye, money);this.height = height;this.weight = weight;}
}
Demo类:
package com.reflect.fieldexample;import java.lang.reflect.Field;public class Demo {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {// 加载类Class<?> classAsianPerson = Class.forName("com.reflect.fieldexample.AsianPerson");// 创建类实例Object person = classAsianPerson.newInstance();// 获取public属性对象Field field = classAsianPerson.getField("weight");System.out.println("修改前weight:" + field.get(person));field.set(person, 120);System.out.println("修改后weight:" + field.get(person));System.out.println();// 获取属性类型System.out.println("weight变量类型:" + field.getType());System.out.println();// 获取private属性对象Field field2 = classAsianPerson.getDeclaredField("height");// 设置允许访问field2field2.setAccessible(true);System.out.println("修改前height:" + field2.get(person));field2.set(person, 175);System.out.println("修改后height:" + field2.get(person));System.out.println();// 获取静态属性对象Field field3 = classAsianPerson.getDeclaredField("IQ");// 设置允许访问field3field3.setAccessible(true);System.out.println("修改前IQ:" + field3.get(person));field3.set(person, 201);System.out.println("修改后IQ:" + field3.get(person));// 静态属性可以使用nullfield3.set(null, 250);System.out.println("修改后IQ:" + field3.get(null));System.out.println();}
}
3. Method
(1) 常用方法
方法 | 作用 |
---|---|
invoke(Object obj, Object... args) | 通过obj对象传入args参数调用方法,静态方法obj可以为null |
getParameterTypes() | 获取方法参数类型 |
setAccessible(boolean flag) | 设置是否可以访问private方法, true表示允许访问,false表示不允许访问 |
(2) 使用示例
Phone类:
package com.reflect.methodexample;public class Phone {public void call(String phoneNumber) {System.out.println("拨打电话" + phoneNumber);}private void fixedPosition() {System.out.println("移动不方便,通常放在固定地点");}
}
MobilePhone类:
package com.reflect.methodexample;public class MobilePhone extends Phone{public void listenMusic(String name) {System.out.println("播放音乐<" + name + ">");}private void movedPosition() {System.out.println("携带方便,随时随地可以使用");}private static void sendMessage() {System.out.println("发短信");}
}
Demo类:
package com.reflect.methodexample;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class Demo {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {Class classMobilePhone = Class.forName("com.reflect.methodexample.MobilePhone");Object phone = classMobilePhone.newInstance();// 获取public方法Method method = classMobilePhone.getMethod("listenMusic", String.class);// 调用方法method.invoke(phone, "男儿当自强");Method method2 = classMobilePhone.getMethod("call", String.class);method2.invoke(phone, "11111111");// 获取方法参数类型Class<?>[] parameterTypes = method2.getParameterTypes();for (Class<?> parameterType : parameterTypes) {System.out.println("参数类型:" + parameterType);}// 获取private方法Method method3 = classMobilePhone.getDeclaredMethod("movedPosition");// 设置可以访问private方法method3.setAccessible(true);method3.invoke(phone);Method method4 = classMobilePhone.getDeclaredMethod("sendMessage");method4.setAccessible(true);method4.invoke(phone);method4.invoke(null);}
}
4. Constructor
(1) 常用方法
方法 | 作用 |
---|---|
newInstance(Object... initArgs) | 根据参数调用构造器实例化对象 |
getParameterTypes() | 获取构造器参数类型 |
setAccessible(boolean flag) | 设置是否可以访问构造器,flag为true表示允许访问,flag为false表示不允许访问 |
(2) 使用示例
Apple类:
package com.reflect.construtorexample;public class Apple {public double price = 10;public String name = "苹果";public Apple() {}private Apple(double price) {this.price = price;}public Apple(double price, String name) {this.price = price;this.name = name;}@Overridepublic String toString() {return "Apple{" +"price=" + price +", name='" + name + '\\'' +'}';}
}
Demo类:
package com.reflect.construtorexample;import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;public class Demo {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {Class<?> classApple = Class.forName("com.reflect.construtorexample.Apple");// 获取无参构造Constructor<?> declaredConstructor = classApple.getDeclaredConstructor();Object apple = declaredConstructor.newInstance();System.out.println(apple);// 获取public构造Constructor<?> declaredConstructor2 = classApple.getDeclaredConstructor(double.class, String.class);Object apple2 = declaredConstructor2.newInstance(14, "黄元帅");System.out.println(apple2);// 获取参数列表Class<?>[] parameterTypes = declaredConstructor2.getParameterTypes();for (Class<?> parameterType : parameterTypes) {System.out.println("\\t\\t参数类型:" + parameterType);}// 获取private构造Constructor<?> declaredConstructor3 = classApple.getDeclaredConstructor(double.class);// 设置可以访问构造器declaredConstructor3.setAccessible(true);Object apple3 = declaredConstructor3.newInstance(19);System.out.println(apple3);}
}