Java反射机制:是指在运行时去获取一个类的变量和方法信息,然后通过获取到的信息来创建对象,调用方法的一种机制。由于这种动态性,可以极大的增强程序的灵活性,程序不用在编译期就完成确定,在运行期仍然可以扩展。
获取Class类的对象我们要想通过反射去使用一个类,首先我们要获取到该类的字节码文件对象,也就是类型为Class类型的对象
这里我们介绍三种方式获取Class类型的对象
Student类
public class Student {private String name;
int age;
public String address;
public Student() {}
private Student(String name) {this.name = name;
}
Student(String name,int age) {this.name = name;
this.age = age;
}
public Student(String name, int age, String address) {this.name = name;
this.age = age;
this.address = address;
}
private void function() {System.out.println("function");
}
public void method1 () {System.out.println("method");
}
public void method2 (String s) {System.out.println("method" + s);
}
public String method3 (String s, int i) {return s + "," + i;
}
@Override
public String toString() {return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}
测试反射类
public class ReflectTest {public static void main(String[] args) throws ClassNotFoundException {// 使用类的class属性来获取该类对应的Class对象
Classc1 = Student.class;
Classc2 = Student.class;
System.out.println(c1);
System.out.println(c1 == c2);// true
System.out.println("==========");
// 调用对象的getClass()方法,返回该对象所属类对应的Class对象
Student s = new Student();
Class extends Student>c3 = s.getClass();
System.out.println(c1 == c3);// true
System.out.println("==========");
// 使用Class类中的静态方法forName(String className)
Class>c4 = Class.forName("com.example.fanshe.Student");
System.out.println(c1 == c4);// true
}
}
反射获取构造方法并使用public class ReflectTest {public static void main(String[] args) {// 得到Student类的字节码文件对象
ClassstudentClass = Student.class;
Constructor>[] constructors = studentClass.getConstructors();
for (Constructor>con : constructors) {System.out.println(con);
}
}
}
public class ReflectTest {public static void main(String[] args) {// 得到Student类的字节码文件对象
ClassstudentClass = Student.class;
Constructor>[] constructors = studentClass.getDeclaredConstructors();
for (Constructor>con : constructors) {System.out.println(con);
}
}
}
public class ReflectTest {public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, InstantiationException, IllegalAccessException {// 得到Student类的字节码文件对象
ClassstudentClass = Student.class;
// 拿到无参公共构造方法
Constructorconstructor = studentClass.getConstructor();
// 使用反射方式创建对象
Student student = constructor.newInstance();
System.out.println(student);
}
}
public class ReflectTest {public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, InstantiationException, IllegalAccessException {ClassstudentClass = Student.class;
// 拿到无参公共构造方法
//Constructorconstructor = studentClass.getConstructor();
// 拿到3个参数的构造方法
Constructorconstructor = studentClass.getConstructor(String.class,
int.class, String.class);
// 使用反射方式创建对象
Student student = constructor.newInstance("小米", 19, "广东");
System.out.println(student);
}
}
基本数据类型同样可以通过class属性得到对应的Class类型
newInstance()方法:创建反射类对应的类的实例
public class ReflectTest {public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, InstantiationException, IllegalAccessException {// 得到Student类的字节码文件对象
ClassstudentClass = Student.class;
// 拿到指定构造函数
Constructorconstructor = studentClass.getDeclaredConstructor(String.class);
// 取消访问检查,以便使用私有构造方法创建对象
constructor.setAccessible(true);
Student student = constructor.newInstance("小米");
System.out.println(student);
}
}
public void setAccessible(boolean flag)
这个方法用于取消访问检查,暴力反射机制
Class类方法 | 说明 |
---|---|
public Field[] getFields() | 返回所有公共字段数组 |
public Field[] getDeclaredFields() | 返回所有字段数组 |
public Field getField(String name) | 返回指定公共字段 |
public Field getDeclaredField(String name) | 返回指定字段 |
public class ReflectTest {public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, InstantiationException,
IllegalAccessException, NoSuchFieldException {// 得到Student的字节码对象
ClassstudentClass = Student.class;
// 得到address字段
Field addressField = studentClass.getDeclaredField("address");
// 得到name字段
Field nameField = studentClass.getDeclaredField("name");
// 得到无参构造方法
Constructorconstructor = studentClass.getConstructor();
// 创建对象
Student student = constructor.newInstance();
// 取消访问检查
nameField.setAccessible(true);
// 为字段设置值
addressField.set(student, "西安");
nameField.set(student, "小米");
// 打印
System.out.println(student);
}
}
public void set(Object obj, Object value)
为字段设置值
参数说明:
Class类方法 | 说明 |
---|---|
public Method[] getMethods() | 返回所有公共方法数组(包含继承过来的) |
public Method[] getDeclaredMethods() | 返回所有方法数组(不包含继承的) |
public Method getMethod(String name, Class>… parameterTypes) | 返回指定的公共方法 |
public Method getDeclaredMethod(String name, Class>… parameterTypes) | 返回指定的方法 |
public class ReflectTest {public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, InstantiationException,
IllegalAccessException {// 得到Student的字节码对象
ClassstudentClass = Student.class;
// 得到method1方法
Method method = studentClass.getDeclaredMethod("method1");
// 得到method2方法
Method method2 = studentClass.getMethod("method2", String.class);
// 得到method3方法
Method method3 = studentClass.getMethod("method3", String.class, int.class);
// 得到function方法
Method function = studentClass.getDeclaredMethod("function");
// 得到公共的无参构造方法
Constructorconstructor = studentClass.getConstructor();
Student student = constructor.newInstance();
// 调用方法
method.invoke(student);
method2.invoke(student, "s");
Object s = method3.invoke(student, "s", 1);
System.out.println(s);
function.setAccessible(true);
function.invoke(student);
}
}
public Object invoke(Object obj, Object... args)
调用方法
参数说明:
Class类方法 | 说明 |
---|---|
public< A extends Annotation >A getAnnotation(Class< A >annotationClass) | 获取指定的注解信息 |
public class ReflectTest {public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, InstantiationException,
IllegalAccessException, NoSuchFieldException {ArrayListarrays = new ArrayList<>();
Class extends ArrayList>aClass = arrays.getClass();
Method add = aClass.getMethod("add", Object.class);
add.invoke(arrays, "word");
System.out.println(arrays);
}
}
需求二:通过配置文件运行类中的指定方法public class ReflectTest {public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, InstantiationException,
IllegalAccessException, ClassNotFoundException, IOException {// 加载数据
Properties prop = new Properties();
FileReader fr = new FileReader("src\\main\\java\\com\\example\\fanshe\\class.properties");
prop.load(fr);
fr.close();
String className = prop.getProperty("className");
String methodName = prop.getProperty("methodName");
// 得到字节码文件对象
Class>aClass = Class.forName(className);
// 得到无参构造方法
Constructor>constructor = aClass.getConstructor();
// 创建对象
Object o = constructor.newInstance();
// 得到method1方法
Method method1 = aClass.getMethod(methodName);
// 调用方法
method1.invoke(o);
}
}
class.properties文件如下:
className=com.example.fanshe.Student
methodName=method1
需求三,使用注解替代配置文件@MyAnnotation(className = "com.example.fanshe.Student",methodName = "method1")
public class ReflectTest {public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, InstantiationException,
IllegalAccessException, ClassNotFoundException, IOException {// 通过注解来运行指定类中的指定方法
ClassreflectTestClass = ReflectTest.class;
MyAnnotation annotation = reflectTestClass.getAnnotation(MyAnnotation.class);
String className = annotation.className();
String methodName = annotation.methodName();
// 得到字节码文件对象
Class>aClass = Class.forName(className);
// 得到无参构造方法
Constructor>constructor = aClass.getConstructor();
// 创建对象
Object o = constructor.newInstance();
// 得到method1方法
Method method1 = aClass.getMethod(methodName);
// 调用方法
method1.invoke(o);
}
}
注解定义如下:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {String className();
String methodName();
}
这就是框架常用到的技术了,后期在谈到框架时我们在深入讨论,那么今天就先到这里了
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧