1、什么是反射
(1)Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到类对象之后,再通过类对象进行反编译,从而获取对象的各种信息。
(2)Java属于先编译再运行的语言,程序中对象的类型在编译期就确定下来了,而当程序在运行时可能需要动态加载某些类,这些类因为之前用不到,所以没有被加载到JVM。通过反射,可以在运行时动态地创建对象并调用其属性,不需要提前在编译期知道运行的对象是谁
所以,能够分析信息的能力叫做反射。
2、反射如何工作
这里涉及到了类的生命周期
3、class对象的常用功能
public class Dog {
private Integer age = 18;
public String name = "小花";
protected Character sex = '男';
String color = "白色";
public Dog(){
}
public Dog(String name){
this.name = name;
}
private Dog(String name,Integer age){
this.name = name;
this.age = age;
}
public void run(int mum){
System.out.println("小花跑的很快"+mum);
}
public void run(){
System.out.println("小花吃的很多");
}
private void flay(){
System.out.println("狗不能飞");
}
private void jump(int num,String name){
System.out.println(name + "能跳" + num + "米");
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Character getSex() {
return sex;
}
public void setSex(Character sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Dog{" +
"age=" + age +
", name='" + name + '\'' +
", sex=" + sex +
'}';
}
}
一、关于全局变量
1.关于获取全局变量
类对象名称.getFields(); // Field[]数组进行接收 只能获取由public修饰的变量
类对象名称.getDeclaredFields(); // Field[]数组进行接收 能获取所有的变量
类对象名称.getField("指定的变量") // Field 进行接收 只能获取由public修饰的变量
类对象名称.getDeclaredField("指定的变量"); // Field数组进行接收 能获取所有的变量
2.Field成员变量的基本操作
// 1.设置值 set(Object obj,Object value)
①:new出我们的对象 :我们需要给赋的值内存空间进行表达
②:判断我们所获取的变量是不是private类型的,如果是必须使用暴力反射 : setAccessible(true);
②:调用set()方法,传递两个参数,第一个我们new出来的对象,第二个使我们想要付的值
// 2.获取值 get(Object obj)
①:new出我们的对象:我们需要给赋的值内存空间进行表达
②:判断我们所获取的变量是不是private类型的,如果是必须使用暴力反射 : setAccessible(true);
③:调用get()方法并且将创建出来的对象当成参数进行传递,用Object来进行返回值的接收
import java.lang.reflect.Field;
public class Text1 {
public static void main(String[] args) throws Exception {
Class class1 = Class.forName("fanshe.Dog");
Field[] fields = class1.getFields();
for(Field field:fields) {
System.out.println(field);
}
System.out.println("-------------");
Field[] fields1 = class1.getDeclaredFields();
for(Field field: fields1) {
System.out.println(field);
}
System.out.println("-------------");
Field fieldName = class1.getField("name");
System.out.println(fieldName);
Dog dog = new Dog();
fieldName.set(dog, "小黑");
Object o = fieldName.get(dog);
System.out.println(o);
System.out.println("-------------");
Field fieldAge = class1.getDeclaredField("age");
System.out.println(fieldAge);
Dog dog1 = new Dog();
fieldAge.setAccessible(true);
fieldAge.set(dog1, 20);
fieldAge.setAccessible(true);
Object o1 = fieldAge.get(dog1);
System.out.println(o1);
}
}
二、关于方法
1.关于获取方法
类对象名称.getMethods(); //Method[]数组进行接收 只能获取由public修饰的方法
类对象名称.getDeclaredMethods(); //Method[]数组进行接收 获取由所有的的方法
类对象名称.getMethod("制定的方法名称",参数类型.class.....); //Method进行接收 只能获取由public修饰的方法
类对象名称.getDeclaredMethod("制定的方法名称",参数类型.class ....); //Method数组进行接收 获取由所有的的方法
2.关于对方法的操作 invoke() //对方法的执行
①:new出我们的对象 :我们需要给方法内存空间进行表达
②:判断我们所获取的方法是不是private类型的,如果是必须使用暴力反射 : setAccessible(true);
②:调用invkoe()方法,传递两个参数,第一个我们new出来的对象,第二个使我们想要付的值
import java.lang.reflect.Method;
public class Text {
public static void main(String[] args) throws Exception {
//class.forName("全类名");
Class class1 = Class.forName("sort.Dog");
Method[] method1 = class1.getMethods();
for (Method megide:method1) {
System.out.println(megide);
}
System.out.println("--------------");
Method[] methods2 = class1.getDeclaredMethods();
for ( Method method: methods2) {
System.out.println(method);
}
System.out.println("-------------------");
//单独获取没有参数的public 修饰的方法
Method RunMethod = class1.getMethod("run");
System.out.println(RunMethod);
// 1.创建对象
Dog dog = new Dog();
// 2.调用invoke()方法
RunMethod.invoke(dog);
System.out.println("------------------------");
//单独获取有参数的public 修饰的方法
Method RunMethod1 = class1.getMethod("run",int.class);
System.out.println(RunMethod1);
Dog dog1 = new Dog();
RunMethod1.invoke(dog1,1000);
System.out.println("------------------------");
//单独获取没有参数的private修饰的方法
Method flayMethod = class1.getDeclaredMethod("flay");
System.out.println(flayMethod);
Dog dog2 = new Dog();
//暴力反射
flayMethod.setAccessible(true);
flayMethod.invoke(dog2);
System.out.println("------------------");
Method jumpMethod = class1.getDeclaredMethod("jump", int.class, String.class);
System.out.println(jumpMethod);
Dog dog3 = new Dog();
jumpMethod.setAccessible(true);
jumpMethod.invoke(dog3,100,"校长");
}
}
三、关于构造器
类对象名称.getConstructors(); // Constructor[]数组进行接收 只能获取由public修饰的构造器
类对象名称.getDeclaredConstructors(); // Constructor[]数组进行接收 能获取所有的构造器
类对象名称.getConstructor(参数类型.class) //
类对象名称.getDeclaredConstructor(参数类型.class); //
2. newInstance()
import java.lang.reflect.Constructor;
public class text2 {
public static void main(String[] args)throws Exception{
//class.forName("全类名");
Class class1 = Class.forName("fanshe.Dog");
Constructor[] constructors1 = class1.getConstructors();
for (Constructor con: constructors1
) {
System.out.println(con);
}
System.out.println("--------------------------");
Constructor[] constructors2 = class1.getDeclaredConstructors();
for (Constructor con: constructors2
) {
System.out.println(con);
}
System.out.println("--------------------------");
Constructor constructor = class1.getConstructor();
Object o = constructor.newInstance();
System.out.println(o);
System.out.println(constructor);
System.out.println("--------------------------");
Constructor constructor1 = class1.getConstructor(String.class);
System.out.println(constructor1);
Object o1 = constructor1.newInstance("小白");
System.out.println(o1);
System.out.println("--------------------------");
Constructor declaredConstructor = class1.getDeclaredConstructor(String.class, Integer.class);
System.out.println(declaredConstructor);
declaredConstructor.setAccessible(true);
Object o2 = declaredConstructor.newInstance("小白", 20);
System.out.println(o2);
}
}