一.反射的概念
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
通俗的说,java虚拟机在加载类的时候会找到对应的class文件,并生成一个class对象,每个类class对象只会生成一次,就算是基本数据类型,也会有一个class对象,所以说在java中一切皆对象,这里引入一位博主的图片,我觉得概括的很好
图片来自[https://blog.csdn.net/sinat_38259539/article/details/71799078]
二.反射中使用的方法
1.获取class对象的方法
package Test;
public class ReflectTest {
public static void main(String[] args) throws Exception{
Student s1 = new Student();
Class stu1 = s1.getClass();
System.out.println(stu1.getName());
Class stu2 = Student.class;
System.out.println(stu1==stu2);
//最常用方法
Class stu3 = Class.forName("Test.Student");
System.out.println(stu1==stu3);
}
}
class Student{
}
一般常用第三种方法,第一个都有类的实例了,第二个需要导入类包,第三个forName中的路径为绝对路径。
2.获得类的方法并调用
package Test;
import java.lang.reflect.Method;
public class ReflectTest {
public static void main(String[] args) throws Exception{
ReflectTest obj = new ReflectTest();
Method m1 = obj.getClass().getMethod("age",int.class);
m1.invoke(obj, new Integer(27));
m1.invoke(obj, 28);
Method m2 = obj.getClass().getMethod("age",Integer.class);
m2.invoke(obj, new Integer(27));
m2.invoke(obj,28);
}
public void age(int age) {
System.out.println("int age = " + age);
}
public void age(Integer age) {
System.out.println("Integer age = " + age);
}
}
输出:
int age = 27
int age = 28
Integer age = 27
Integer age = 28
3.获取类信息的系列方法
以Singer类为例子
package Test;
public class Singer {
public String name;
public String sex;
private String song;
public Singer() {
}
public Singer(String name, String sex, String song) {
this.name = name;
this.sex = sex;
this.song = song;
}
public void setName(String name) {
this.name = name;
}
public void setSex(String sex) {
this.sex = sex;
}
public void setSong(String song) {
this.song = song;
}
public String getName() {
return name;
}
public String getSex() {
return sex;
}
public String getSong() {
return song;
}
}
package Test;
import java.lang.reflect.*;
public class ReflectTest1 {
public static void main(String[] args) throws Exception{
Class clazz = Class.forName("Test.Singer");
//获得所有方法
Method[] methods = clazz.getDeclaredMethods();
for (Method m: methods) {
System.out.println(m);
}
//获取所有成员属性变量
Field[] fields = clazz.getDeclaredFields();
for (Field f: fields) {
System.out.println(f);
}
//获取所有构造方法
Constructor[] constructors = clazz.getDeclaredConstructors();
for (Constructor c: constructors) {
System.out.println(c);
}
}
}
输出:
public java.lang.String Test.Singer.getName()
public void Test.Singer.setName(java.lang.String)
public java.lang.String Test.Singer.getSex()
public java.lang.String Test.Singer.getSong()
public void Test.Singer.setSex(java.lang.String)
public void Test.Singer.setSong(java.lang.String)
public java.lang.String Test.Singer.name
public java.lang.String Test.Singer.sex
private java.lang.String Test.Singer.song
public Test.Singer()
public Test.Singer(java.lang.String,java.lang.String,java.lang.String)
三. 总结
- 获得Class对象
- 调用Class的方法
- 使用反射API来操作信息
原文地址:https://www.cnblogs.com/authetic/p/8972091.html
时间: 2024-10-06 22:42:06