目录
前言
反射(Reflection)是Java编程语言中的一种强大机制,它允许程序在运行时检查或修改类的行为。通过使用反射,程序可以访问类的内部属性和方法,即使这些属性和方法是在编译时未知的。
反射
1.反射是什么?
反射是一种获取类信息的能力
类信息包括:方法、变量、接口、父类、构造器、类名....
2.为什么会有反射?
需要获取类信息
3.反射是如何工作的?
程序运行有三个阶段:磁盘阶段、类对象阶段、运行时阶段
想要反射获取类信息就必须进入第二阶段:类对象阶段
4.进入第二阶段的三种方案
在磁盘阶段:Class.forName("全类名") 全类名:包名加类名
在类对象阶段:类名.class
在运行时阶段:对象名.getClass()
示例:
package 反射;
public class Student {
private String name="张三";
public Integer age=18;
Character sex='男';
protected Double height =170.0;
}
package 反射;
public class Test {
public static void main(String[] args) throws Exception{
//想要获取类信息就必须进入类对象阶段
Class class1=Class.forName("反射.Student");
Class class2=Student.class;
Student student=new Student();
Class class3=student.getClass();
System.out.println(class1==class2);
System.out.println(class2==class3);
}
}
输出结果为:
true
true
==比较的是指向的地址是否相同,说明class1,class2,class3全指向了同一区域,方法区中
同一个对象,会在方法区里面留下同一个类对象
5.获取变量信息
获取全部的全局变量信息 getDeclaredFields()
获取public修饰的全局变量信息 getFields()
获取指定的全局变量信息 getDeclaredField()
获取指定的public修饰的全局变量信息 getField()
package 反射;
public class Student {
private String name="张三";
public Integer age=18;
Character sex='男';
protected Double height =170.0;
public String color = "蓝色";
}
package 反射;
import java.lang.reflect.Field;
import java.util.Arrays;
public class Test {
public static void main(String[] args) throws Exception {
//想要获取类信息就必须进入类对象阶段
Class class1 = Class.forName("反射.Student");
//获取全部的全局变量信息,并且打印
Field[] fields = class1.getDeclaredFields();
System.out.println(Arrays.toString(fields));
//获取public修饰的全局变量信息,并且打印
Field[] fields1 = class1.getFields();
System.out.println(Arrays.toString(fields1));
System.out.println("-----------------");
//获取指定的全局变量信息并且打印
Field nameField = class1.getDeclaredField("name");
System.out.println(nameField);
Field heightField = class1.getDeclaredField("height");
System.out.println(heightField);
Field ageField = class1.getDeclaredField("age");
System.out.println(ageField);
System.out.println(".........................");
//获取指定的public修饰的全局变量信息并且打印
// Field nameField1 = class1.getField("name");//此行代码报错 因为name为private访问修饰符修饰而非public修饰
// System.out.println(nameField1);
// Field heightField1 = class1.getField("height");//此行代码报错 因为height为protected访问修饰符修饰而非public修饰
// System.out.println(heightField1);
Field ageField1 = class1.getField("age");
System.out.println(ageField1);
System.out.println("//");
}
}
输出结果为:
[private java.lang.String 反射.Student.name, public java.lang.Integer 反射.Student.age, java.lang.Character 反射.Student.sex, protected java.lang.Double 反射.Student.height, public java.lang.String 反射.Student.color]
[public java.lang.Integer 反射.Student.age, public java.lang.String 反射.Student.color]
-----------------
private java.lang.String 反射.Student.name
protected java.lang.Double 反射.Student.height
public java.lang.Integer 反射.Student.age
.........................
public java.lang.Integer 反射.Student.age
//
6.获取方法信息
获取所有方法的信息 getDeclaredMethods()
获取public修饰的所有的方法的信息 getMethods()
获取指定的方法信息 getDeclaredMethod()
获取指定的,且是public的方法信息 getMethod()
package 反射;
public class Student {
private String name="张三";
public Integer age=18;
Character sex='男';
protected Double height=170.0;
public String color = "蓝色";
public void run(){}
private int getAge(int age){
return age;
}
void aaa(String name,Integer height){
}
protected void haha(String name,int age){
}
}
package 反射;
import java.lang.reflect.Method;
import java.util.Arrays;
public class Test {
public static void main(String[] args) throws Exception {
//想要获取类信息就必须进入类对象阶段
Class class1 = Class.forName("反射.Student");
//获取所有方法的信息
Method[] declaredMethods = class1.getDeclaredMethods();
System.out.println(Arrays.toString(declaredMethods));
//获取public修饰的所有的方法的信息
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);
//获取指定的,且是public的方法
Method run1 = class1.getMethod("run");
System.out.println(run1);
}
}
输出结果为:
7.获取构造器信息
获取所有构造器的信息 getDeclaredConstructors()
获取所有pubulic修饰的构造器的信息 getConstructors()
获取指定构造器的信息 getDeclaredConstructor()
获取指定且被public修饰的构造器的信息 getConstructor()
package 反射;
public class Student {
private String name="张三";
public Integer age=18;
Character sex='男';
protected Double height=170.0;
public String color = "蓝色";
public void run(){}
private int getAge(int age){
return age;
}
void aaa(String name,Integer height){
}
protected void haha(String name,int age){
}
public Student() {
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
public Student(String name, Integer age, Character sex, Double height, String color) {
this.name = name;
this.age = age;
this.sex = sex;
this.height = height;
this.color = color;
}
}
package 反射;
import java.lang.reflect.Constructor;
import java.util.Arrays;
public class Test {
public static void main(String[] args) throws Exception {
//想要获取类信息就必须进入类对象阶段
Class class1 = Class.forName("反射.Student");
//获取所有构造器的信息
Constructor[] declaredConstructors = class1.getDeclaredConstructors();
System.out.println(Arrays.toString(declaredConstructors));
//获取所有pubulic修饰的构造器的信息
Constructor[] constructors = class1.getConstructors();
System.out.println(Arrays.toString(constructors));
//获取指定构造器的信息
Constructor declaredConstructor = class1.getDeclaredConstructor();
System.out.println(declaredConstructor);
Constructor declaredConstructor1 = class1.getDeclaredConstructor(String.class, Integer.class);
System.out.println(declaredConstructor1);
Constructor declaredConstructor2 = class1.getDeclaredConstructor(String.class, Integer.class, Character.class, Double.class, String.class);
System.out.println(declaredConstructor2);
//获取指定且被public修饰的构造器的信息
Constructor constructor = class1.getConstructor();
System.out.println(constructor);
Constructor constructor1 = class1.getConstructor(String.class, Integer.class);
System.out.println(constructor1);
Constructor constructor2 = class1.getConstructor(String.class, Integer.class, Character.class, Double.class, String.class);
System.out.println(constructor2);
}
}
输出的结果为:
8.获取构造器,然后使用
package 反射;
public class Student {
private String name="张三";
public Integer age=18;
Character sex='男';
protected Double height=170.0;
public String color = "蓝色";
public void run(){}
private int getAge(int age){
return age;
}
void aaa(String name,Integer height){
}
protected void haha(String name,int age){
}
//私有的构造器
private Student() {
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
public Student(String name, Integer age, Character sex, Double height, String color) {
this.name = name;
this.age = age;
this.sex = sex;
this.height = height;
this.color = color;
}
}
package 反射;
import java.lang.reflect.Constructor;
public class Test {
public static void main(String[] args) throws Exception {
//想要获取类信息就必须进入类对象阶段
Class class1 = Class.forName("反射.Student");
//获取指定构造器的信息
Constructor declaredConstructor = class1.getDeclaredConstructor(String.class, Integer.class);
//创建对象
Student student1 = (Student) declaredConstructor.newInstance("aaa",18);//需要使Object类型强转为Student类型
Constructor declaredConstructor1 = class1.getDeclaredConstructor();
//private修饰的数据,想要使用就必须暴力反射
declaredConstructor1.setAccessible(true);
Student student2 = (Student) declaredConstructor1.newInstance();
}
}
9.获取方法,然后调用
package 反射;
public class Student {
private String name="张三";
public Integer age=18;
Character sex='男';
protected Double height=170.0;
public String color = "蓝色";
public void run(){
System.out.println("这是run()");
}
private int getAge(int age){
System.out.println("这是age()");
return age;
}
void aaa(String name,Integer height){
System.out.println("这是aaa()");
}
protected void haha(String name,int age){
System.out.println("这是haha()");
}
private Student() {
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
public Student(String name, Integer age, Character sex, Double height, String color) {
this.name = name;
this.age = age;
this.sex = sex;
this.height = height;
this.color = color;
}
}
package 反射;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
public class Test {
public static void main(String[] args) throws Exception{
//想要获取类信息就必须进入类对象阶段
Class class1 = Class.forName("反射.Student");
//获取构造器的类信息
Constructor declaredConstructor = class1.getDeclaredConstructor(String.class, Integer.class);
//创建对象
Student student1=(Student)declaredConstructor.newInstance("aaa",18);//给构造器传入数据
//需要使Object类型强转为Student类型
Method run = class1.getDeclaredMethod("run");//获取指定的run()方法
Object invoke = run.invoke(student1);
//invoke()中传对象和给方法的参数,这里使用的是run()一个无参方法,所以只写对象
//传对象的原因,方法要想使用就必须在内存中开辟空间
Method getAge = class1.getDeclaredMethod("getAge", int.class);//获取指定的getAge()方法
getAge.setAccessible(true);//暴力反射 getAge是private修饰的
getAge.invoke(student1,18);//传对象,传参数
Method aaa=class1.getDeclaredMethod("aaa",String.class,Integer.class);
aaa.invoke(student1,"admin",199);
Method haha=class1.getDeclaredMethod("haha",String.class,int.class);
haha.invoke(student1,"admin",99);
}
}
输出结果为:
这是run()
这是getAge()
这是aaa()
这是haha()
10.获取变量,并赋值
package 反射;
public class Student {
private String name="张三";
public Integer age=18;
Character sex='男';
protected Double height=170.0;
public String color = "蓝色";
}
package 反射;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
public class Test {
public static void main(String[] args) throws Exception {
//想要获取类信息就必须进入类对象阶段
Class class1 = Class.forName("反射.Student");
//获取构造器的类信息
Constructor declaredConstructor = class1.getDeclaredConstructor(String.class, Integer.class);
//创建对象
Student student1=(Student)declaredConstructor.newInstance("aaa",18);//给构造器传入数据
//需要使Object类型强转为Student类型
Field name = class1.getDeclaredField("name");//指定获取变量name的信息
//暴力反射
name.setAccessible(true);
name.set(student1,"admin");//赋值
System.out.println(name.get(student1));
Field age = class1.getDeclaredField("age");
age.set(student1,88);
System.out.println(age.get(student1));
Field sex = class1.getDeclaredField("sex");
sex.set(student1,'女');
System.out.println(sex.get(student1));
Field height = class1.getDeclaredField("height");
height.set(student1,175.5);
System.out.println(height.get(student1));
}
}
输出结果为:
admin
88
女
175.5
11.测试题
Student类
获取该类的构造方法来构造对象,获取该类的名称和该类中每一个变量的名称和方法的名称,并执行相关方法,给每一个变量赋值,并获取值,执行每一个构造方法,执行相应的方法
package 反射test;
//获取该类的构造方法来构造对象,获取该类的名称和该类中每一个变量的名称和方法的名称,并执行相关方法,给每一个变量赋值,并获取值,执行每一个构造方法,执行相应的方法
public class Student {
private String name;
private int age;
private String address;
public Student(String name,int age,String address){
this.address = address;
this.age = age;
this.name = name;
}
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;
}
public String getAddress(){
return address;
}
public void setAddress(String address){
this.address = address;
}
}
Test类
package 反射test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
public class Test {
public static void main(String[] args) throws Exception {
Class class1 = Class.forName("反射test.Student");
//执行构造方法
Constructor declaredConstructor = class1.getDeclaredConstructor(String.class, int.class, String.class);
//创建对象
Student student1 = (Student) declaredConstructor.newInstance("保定", 23, "li");
//获取类名
String className = class1.getSimpleName();
System.out.println(className);
System.out.println("-------------------");
//获取所有变量名
Field[] declaredFields = class1.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField.getName());
}
System.out.println("+++++++++++++++++++");
//获取所有的方法名
Method[] declaredMethods = class1.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod.getName());
}
System.out.println("````````````````````");
//给每一个变量赋值
Field name = class1.getDeclaredField("name");
name.setAccessible(true);
name.set(student1,"zhangsan");
System.out.println(name.get(student1));
Field age = class1.getDeclaredField("age");
age.setAccessible(true);
age.set(student1,27);
System.out.println(age.get(student1));
Field address = class1.getDeclaredField("address");
address.setAccessible(true);
address.set(student1,"河北");
System.out.println(address.get(student1));
System.out.println("~~~~~~~~~~~~~~~~~~~~~");
//执行每一个方法
Method setName = class1.getDeclaredMethod("setName", String.class);
setName.invoke(student1,"li");
Method setAge = class1.getDeclaredMethod("setAge", int.class);
setAge.invoke(student1,32);
Method setAddress = class1.getDeclaredMethod("setAddress", String.class);
setAddress.invoke(student1,"北京");
Method getName = class1.getDeclaredMethod("getName");
System.out.println(getName.invoke(student1));
Method getAge = class1.getDeclaredMethod("getAge");
System.out.println(getAge.invoke(student1));
Method getAddress = class1.getDeclaredMethod("getAddress");
System.out.println(getAddress.invoke(student1));
输出结果为:
Student
-------------------
name
age
address
+++++++++++++++++++
getAddress
getName
setName
setAge
getAge
setAddress
````````````````````
zhangsan
27
河北
~~~~~~~~~~~~~~~~~~~~~
li
32
北京