反射
- 介绍
- Class类
- 创建对象
- 测试代码
- 运行结果
- 属性
- 测试代码
- 运行结果
- 构造方法
- 测试代码
- 运行结果
- 成员方法
- 测试代码
- 运行结果
- 用到的全部代码
- student类
- 运行的全部代码
介绍
Reflection(反射) 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查。被private封装的资源只能类内部访问,外部是不行的,但反射能直接操作类私有属性。
反射可以在运行时获取一个类的所有信息,(包括成员变量,成员方法,构造器等),并且可以操纵类的字段、方法、构造器等部分。通俗点总结就是不通过创建对象的方式来访问类的属性,并且能够访问private修饰的属
性。
Class类
Java反射的基础是Class类,它是Java反射的入口。Class类提供了获取类的构造函数、方法、字段、注解等信息的方法。
创建对象
Class.forName(“类的全路径”)( 例如:com.hqyj.core.io.serializestream.Student)
类名.class
类的对象.getClass();( 不建议)
测试代码
public static void test01() throws Exception{//反射,拿到了类的所有信息,可以走后门//方式一//创建类的Class对象System.out.println("===================================");System.out.println("方式一");Class c1=Class.forName("com.HQSecond.day9.Student");//创建Student对象Student stu1=(Student) c1.newInstance();System.out.println(stu1);System.out.println("===================================");System.out.println("方式二");Class c2=Student.class;Student stu2=(Student) c2.newInstance();System.out.println(stu2);System.out.println("===================================");System.out.println("方式三");Class c3=new Student().getClass();Student stu3=(Student) c3.newInstance();System.out.println(stu3);}
运行结果
属性
Fields[] fields; (存储的是类的成员变量)getField() 根据名字获取public修饰的变量
getFields() 返回类中public修饰的成员变量
getDeclaredField() 根据名字获取所有变量
getDeclaredFields() 返回类中所有的成员变量
测试代码
public static void test02() throws Exception{//创建类的Class对象Class c1=Class.forName("com.HQSecond.day9.Student");//创建Student对象Student stu1=(Student) c1.newInstance();//根据指定名字获取成员变量Field对象中包含了变量的属性(权限修饰符、类型、名字)System.out.println("=========================================");System.out.println("根据指定名字获取成员变量:");Field f= c1.getField("name");System.out.println("变量的名称:"+f.getName());System.out.println("变量的类型:"+f.getType().getName());System.out.println("=========================================");System.out.println("获取类中所有public成员变量:");Field[] fields = c1.getFields();for (Field f1:fields) {System.out.print(f1.getName()+" ");System.out.println(f1.getType());}System.out.println("=========================================");System.out.println("获取类中所有成员变量:");Field[] fields1 = c1.getDeclaredFields();for (Field f1 : fields1) {System.out.print(f1.getName()+" ");System.out.println(f1.getType());}System.out.println("=========================================");System.out.println("给指定的变量赋值:");System.out.println("public变量:");Field f2 = c1.getDeclaredField("name");f2.set(stu1,"Bob");//赋值System.out.println(stu1.getName());//获取System.out.println("private变量:");Field f4 = c1.getDeclaredField("sex");给private修饰的变量赋值,需要设置暴力反射f4.setAccessible(true);f4.set(stu1,"male");//赋值System.out.println(stu1.getSex());//获取}
运行结果
构造方法
Constructors[] constructors;(存储的是类的构造方法)getConstructors();获取类中的所有构造方法getConstructor();获取无参的构造方法getConstructor(String.class, int.class, char.class);
获取有参的构造方法,表明第一个参数为String类型,第二个为int类,第三个为char
测试代码
public static void test03() throws Exception{//方式二 创建class对象Class c1=Student.class;System.out.println("=========================================");System.out.println("获取类中的构造方法:");Constructor[] cons = c1.getConstructors();for (Constructor con : cons) {System.out.println(con);}System.out.println("=========================================");System.out.println("获取无参的构造方法,创对象:");//获取无参的构造方法 创对象---->调用构造方法 调用构造方法----->创对象Constructor con1 = c1.getConstructor();//通过无参构造方法创建Student对象Student Stu1=(Student)con1.newInstance();System.out.println(Stu1);System.out.println("=========================================");System.out.println("获取有参的构造方法,创对象:");//获取有参的构造方法Constructor con2 = c1.getConstructor(String.class, Integer.class);// 通过有参构造创建对象Student stu2=(Student)con2.newInstance("大黄",5);System.out.println(stu2);System.out.println("=========================================");System.out.println("获取有参的构造方法,创对象:");Constructor con3 = c1.getConstructor(String.class, Integer.class,String.class,String.class);Student stu3=(Student)con3.newInstance("Alice",18,"female","ball");System.out.println(stu3.toString());}
运行结果
成员方法
Methods[] methods;(存储的是类的成员方法)getMethod("eat", String.class);(参数1:方法的名称, 参数2:方法形参类型)
测试代码
public static void test04()throws Exception{Class c= Class.forName("com.HQSecond.day9.Student");Student Stu1=(Student)c.newInstance();Stu1.name="Jack";//通过反射调用类中的成员方法 参数1:方法的名称, 参数2:方法形参类型Method m = c.getMethod("getName");//执行方法,传递参数System.out.println(m.invoke(Stu1));//测试2 用set方法设置,get方法获取Method m1 = c.getMethod("setHobby", String.class);m1.invoke(Stu1,"ball");Method m2 = c.getMethod("getHobby");System.out.println(m2.invoke(Stu1));}
运行结果
用到的全部代码
student类
import java.io.Serializable;public class Student implements Serializable {//成员变量//声明一个固定的序列号,此时无论去改变类,序列号都不会变。public static final long serialVersionUID=12345;public String name;public Integer age;private String sex;protected String hobby;//构造方法public Student(){}public Student(String name, Integer age) {this.name = name;this.age = age;}public Student(String name, Integer age, String sex) {this.name = name;this.age = age;this.sex = sex;}public Student(String name, Integer age, String sex, String hobby) {this.name = name;this.age = age;this.sex = sex;this.hobby = hobby;}//成员方法public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public static long getSerialVersionUID() {return serialVersionUID;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getHobby() {return hobby;}public void setHobby(String hobby) {this.hobby = hobby;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", sex='" + sex + '\'' +", hobby='" + hobby + '\'' +'}';}
}
运行的全部代码
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;public class ReflectTest {public static void main(String[] args) throws Exception {test01();test02();test03();test04();}public static void test01() throws Exception{//反射,拿到了类的所有信息,可以走后门//方式一//创建类的Class对象System.out.println("===================================");System.out.println("方式一");Class c1=Class.forName("com.HQSecond.day9.Student");//创建Student对象Student stu1=(Student) c1.newInstance();System.out.println(stu1);System.out.println("===================================");System.out.println("方式二");Class c2=Student.class;Student stu2=(Student) c2.newInstance();System.out.println(stu2);System.out.println("===================================");System.out.println("方式三");Class c3=new Student().getClass();Student stu3=(Student) c3.newInstance();System.out.println(stu3);}public static void test02() throws Exception{//创建类的Class对象Class c1=Class.forName("com.HQSecond.day9.Student");//创建Student对象Student stu1=(Student) c1.newInstance();//根据指定名字获取成员变量Field对象中包含了变量的属性(权限修饰符、类型、名字)System.out.println("=========================================");System.out.println("根据指定名字获取成员变量:");Field f= c1.getField("name");System.out.println("变量的名称:"+f.getName());System.out.println("变量的类型:"+f.getType().getName());System.out.println("=========================================");System.out.println("获取类中所有public成员变量:");Field[] fields = c1.getFields();for (Field f1:fields) {System.out.print(f1.getName()+" ");System.out.println(f1.getType());}System.out.println("=========================================");System.out.println("获取类中所有成员变量:");Field[] fields1 = c1.getDeclaredFields();for (Field f1 : fields1) {System.out.print(f1.getName()+" ");System.out.println(f1.getType());}System.out.println("=========================================");System.out.println("给指定的变量赋值:");System.out.println("public变量:");Field f2 = c1.getDeclaredField("name");f2.set(stu1,"Bob");//赋值System.out.println(stu1.getName());//获取System.out.println("private变量:");Field f4 = c1.getDeclaredField("sex");给private修饰的变量赋值,需要设置暴力反射f4.setAccessible(true);f4.set(stu1,"male");//赋值System.out.println(stu1.getSex());//获取}public static void test03() throws Exception{//方式二 创建class对象Class c1=Student.class;System.out.println("=========================================");System.out.println("获取类中的构造方法:");Constructor[] cons = c1.getConstructors();for (Constructor con : cons) {System.out.println(con);}System.out.println("=========================================");System.out.println("获取无参的构造方法,创对象:");//获取无参的构造方法 创对象---->调用构造方法 调用构造方法----->创对象Constructor con1 = c1.getConstructor();//通过无参构造方法创建Student对象Student Stu1=(Student)con1.newInstance();System.out.println(Stu1);System.out.println("=========================================");System.out.println("获取有参的构造方法,创对象:");//获取有参的构造方法Constructor con2 = c1.getConstructor(String.class, Integer.class);// 通过有参构造创建对象Student stu2=(Student)con2.newInstance("大黄",5);System.out.println(stu2);System.out.println("=========================================");System.out.println("获取有参的构造方法,创对象:");Constructor con3 = c1.getConstructor(String.class, Integer.class,String.class,String.class);Student stu3=(Student)con3.newInstance("Alice",18,"female","ball");System.out.println(stu3.toString());}public static void test04()throws Exception{System.out.println("===============================");System.out.println("通过反射调用类中的成员方法:");Class c= Class.forName("com.HQSecond.day9.Student");Student Stu1=(Student)c.newInstance();Stu1.name="Jack";//通过反射调用类中的成员方法 参数1:方法的名称, 参数2:方法形参类型Method m = c.getMethod("getName");//执行方法,传递参数System.out.println(m.invoke(Stu1));//测试2 用set方法设置,get方法获取Method m1 = c.getMethod("setHobby", String.class);m1.invoke(Stu1,"ball");Method m2 = c.getMethod("getHobby");System.out.println(m2.invoke(Stu1));}
}