在学习反射之前要先知道类实现的过程:
java文件----编译成class文件----new 对象,调用办法
运行时通过Classloader先加载类到内存(class文件—>对象Class)。
Class类中有多个属性和方法。反射就是把这些属性方法等类的组成部分反射成对象,再通过对象去操作类中的各个组成部分。
关于反射的常用方法和使用详情如代码注释:
package Reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestReflection {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException {
//方式一:返回传入(包名.类名)的类或接口相关联的Class
//一般用于框架中,在配置文件中配置类的完全限定名,在程序中通过反射创建对象,访问方法
Class cls = Class.forName("Reflection.Student");
System.out.println(cls);
//方式二通过类名获取
//方法的参数
Class cls2 = Student.class;
//方式三:通过对象获取
//有对象的基础上使用对象反射
//三种方法获取的都是同一个类
Student stu = new Student();
stu.setAge(18);
Class cls3 = stu.getClass();
System.out.println(cls2.getName());//获取类名
System.out.println(cls.getPackage());//获取包名
System.out.println("属性集============================");
Field[] fields = cls.getFields();//获取属性列表,只能返回pubic属性
Field[] fields1 = cls.getDeclaredFields();//获取各种类型属性,忽略访问控制符
for (Field field:fields) {
System.out.println(field);
}
for (Field field:fields1) {
System.out.println(field);
}
System.out.println("单个属性+++++++++++++++++");
//Field field2 = cls.getField("name");//只能返回pubic属性
Field field3 = cls.getDeclaredField("age");//获取各种类型属性,忽略访问控制符
//System.out.println(field2);
System.out.println(field3);
field3.setAccessible(true);//暴力反射,将访问权限修改为true
Object o = field3.get(stu);//获取对象的值,不能访问私有属性(非法访问异常),But通过setAccessible(true)就可以访问
field3.set(stu,20);
System.out.println("方法++++++++++++++++++++++++++++++++++++++++");
Method[] methods = cls.getMethods();//获取的是子类和继承自父类的所以public方法
for (Method method:methods) {
System.out.println(method);
}
System.out.println("自己的方法---------------------------------------------------");
Method[] methods1 = cls.getDeclaredMethods();//获取自己的方法
for (Method method:methods1) {
System.out.println(method);
}
Method getAgeMethod = cls.getDeclaredMethod("getAge");//获取指定方法,可通过传参区分重载的方法
System.out.println(getAgeMethod);
Object o1 = getAgeMethod.invoke(stu);//调用方法,传入对象和参数,返回一个Object类的值
System.out.println(o1);
System.out.println("构造方法+++++++++++++++++++++++++++++++++++++++++++");
Constructor[] constructors = cls.getConstructors();//获取并返回一个构造方法数组
for (Constructor constructor:constructors) {
System.out.println(constructor);
}
Constructor constructor1 = cls.getConstructor(String.class,int.class);//获取构造方法,也可以传参,获取有参构造
System.out.println(constructor1);
//获取到构造方法后,就可以通过构造方法去创建对象
Student stu1 = (Student) constructor1.newInstance("张三",22);//创建对象
System.out.println(stu1);
Student stu2 = (Student) cls.newInstance();//只能创建无参构造
System.out.println(stu2);
}
}
```package Reflection;
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
```java
在这里插入代码片