目录
什么是反射?
反射是一种获取类信息的能力。
类信息:方法、变量、接口、父类、构造器…等一切关于类的信息。
为什么会有反射?
在某些特定的情况下,需要获取类信息。
反射是如何工作的
怎么获取类信息
首先,先看一个小例子。
public static void main(String[] args) throws Exception {
Class class1=Class.forName("sk.sk_08_29.Dog");
Class class2=Dog.class;
Dog dog=new Dog();
Class class3=dog.getClass();
System.out.println(class1==class2);
System.out.println(class2==class3);
}
程序输出:
true
true
原因:
同一个类名只会留下同一个类信息。
获取类信息
先创建一个用于演示的类:
public class Dog extends AnimalBase {
private String name="dog";
public Integer age=1;
Character sex='男';
protected Double height=50.0;
public String color="黑色";
public void run(){
System.out.println("这是run方法");
}
private int getAge(int age){
System.out.println("这是getAge方法");
return age;
}
void aaa(String name,Integer height){
System.out.println("这是aaa方法");
}
protected void haha(String name,int age){
System.out.println("这是haha方法");
}
private Dog(){}
public Dog(String name,Integer age){}
public Dog(String name,Integer age,Character sex){
this.name=name;
this.age=age;
this.sex=sex;
}
}
获取信息代码:
获取所有变量信息
//需要获取类信息就必须进入类对象阶段
Class class1=Class.forName("sk.sk_08_29.Dog");
//获取全部的全局变量信息,并且打印
Field[] files=class1.getDeclaredFields();
System.out.println(Arrays.toString(files));
//获取public修饰的全局变量,并打印
Field[] fields1=class1.getFields();
System.out.println(Arrays.toString(fields1));
System.out.println("-----------------------");
输出:
获取单个变量信息
Field nameFiled=class1.getDeclaredField("name");
System.out.println(nameFiled);
Field ageFiled=class1.getDeclaredField("age");
System.out.println(ageFiled);
Field heightFiled=class1.getDeclaredField("height");
System.out.println(heightFiled);
输出:
不加Declared不能获取到protected修饰的和private修饰的类信息
//Field nameFiled1=class1.getField("name");
//System.out.println(nameFiled1);
Field ageFiled1=class1.getField("age");
System.out.println(ageFiled1);
//Field heightFiled1=class1.getField("height");
//System.out.println(heightFiled1);
输出:
获取全部方法信息
Method[] declearMethods=class1.getDeclaredMethods();
System.out.println(Arrays.toString(declearMethods));
Method[] methods=class1.getMethods();
System.out.println(Arrays.toString(methods));
输出:
获取单个方法信息
Method getAge=class1.getDeclaredMethod("getAge", int.class);
Method aaa=class1.getDeclaredMethod("aaa", String.class, Integer.class);
Method run=class1.getDeclaredMethod("run");
Method hhh=class1.getDeclaredMethod("haha", String.class, int.class);
System.out.println(hhh);
System.out.println(run);
System.out.println(aaa);
System.out.println(getAge);
//方法内无参数时,只需传入名称即可获取
Method run1=class1.getMethod("run");
System.out.println(run1);
输出:
获取构造函数信息
Constructor[] constructors=class1.getConstructors();
System.out.println(constructors);
Constructor[] declareConstructors=class1.getDeclaredConstructors();
System.out.println(Arrays.toString(declareConstructors));
Constructor declareConstructor=class1.getDeclaredConstructor(String.class,Integer.class);
System.out.println(declareConstructor);
输出:
利用反射创建对象
Dog dog1=(Dog) declareConstructor.newInstance("aaa",18);
Constructor declareConstructor1=class1.getDeclaredConstructor();
//private修饰的数据,想要使用就必须暴力反射
declareConstructor1.setAccessible(true);
Dog dog2=(Dog) declareConstructor1.newInstance();
输出:
利用反射创建对象并传参运行方法
Dog dog3=(Dog) declareConstructor.newInstance("aaa",18);
Method run3=class1.getDeclaredMethod("run");
run3.invoke(dog3);
Method getAge2=class1.getDeclaredMethod("getAge", int.class);
getAge2.setAccessible(true);
getAge2.invoke(dog3,18);
Method aaa1=class1.getDeclaredMethod("haha", String.class, int.class);
aaa1.invoke(dog3,"admin",199);
Method haha2=class1.getDeclaredMethod("haha", String.class, int.class);
haha2.invoke(dog3,"admin",199);
输出:
利用反射创建对象并修改初始属性
Field name=class1.getDeclaredField("name");
name.setAccessible(true);
System.out.println(name.get(dog2));
Field age=class1.getDeclaredField("age");
age.set(dog2,2);
System.out.println(age.get(dog2));
Field sex=class1.getDeclaredField("sex");
sex.set(dog2,'女');
System.out.println(sex.get(dog2));
Field height=class1.getDeclaredField("height");
height.set(dog2,13.66);
System.out.println(height.get(dog2));
输出:
至此,文章结束。