Java基础(十一)反射

        本文主要介绍了Java基础中关于反射的相关知识,包括其定义,及应用。

一、什么是反射

        反射是java基础的核心,反射是获取类信息的能力。

        类信息包括:方法、变量、接口、父类、构造器、类名........

二、为什么会有反射

        因为需要获取类信息,所以需要用到反射(new对象也能获取类信息但获取的类信息的能力有限)。

三、反射是如何工作的

        想要反射获取类信息就必须进入类对象阶段,根据下图发现,有三种方式进入类对象阶段 。

1、如何进入类对象阶段

        ①Class.forName("全类名"),全类名为包名加类名

        ②类名.class

        ③对象名.getclass()

四、反射的应用

        创建一个student类,再创建一个test类(注意,下属各个Test代码相加在一起才是完整代码,本文为了方便介绍将整个代码进行了拆分。)。

//Student类
public class Student {
    private String name="张三";
    public Integer age=18;
    Character sex='男';
    protected Double height =185.5;
    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()");
    }
    public Student(){}
    private Student(String name){}
    public Student(String name,Integer 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;
    }
}

1、想要获取类信息就必须进入类对象阶段,以下是进入类对象阶段的三种方式的应用。

public class Test {
    public static void main(String[] args) throws Exception {
       //1、想要获取类信息就必须进入类对象阶段,以下是进入类对象阶段的三种方式
        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);
        System.out.println("------------");
        
   

        结果:

2、以class1为例进行变量信息的获取。


       //2、以class1为例进行变量信息的获取
        //①获取全部的变量信息,并且打印
        Field[] files=class1.getDeclaredFields();
        System.out.println(Arrays.toString(files));
        System.out.println("------------");
        //②获取public修饰的全局变量信息,并打印
        Field[] fiels1=class1.getFields();
        System.out.println(Arrays.toString(fiels1));
        System.out.println("------------");
        //③获取任意一个变量信息
        Field nameField =class1.getDeclaredField("name");
        System.out.println(nameField);
        Field hightField =class1.getDeclaredField("height");
        System.out.println(hightField);
        Field ageField =class1.getDeclaredField("age");
        System.out.println(ageField);
        System.out.println("------------");
        //④获取任意一个public修饰的变量信息
        Field ageField1 =class1.getField("age");
        System.out.println(ageField1);
        System.out.println("------------");
        
    

     结果:

3、以class1为例进行方法信息的获取。


     //3以class1为例进行方法信息的获取
    //①获取全部方法信息
    Method[] declaredMethods=class1.getDeclaredMethods();
    System.out.println(Arrays.toString(declaredMethods));
    System.out.println("------------");
    //②获取public修饰的方法信息
    Method[] methods =class1.getMethods();
    System.out.println(Arrays.toString(methods));
    System.out.println("------------");
    //③获取任意一个方法信息
    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(aaa);
    System.out.println(run);
    System.out.println(getAge);
    System.out.println("------------");
    //④获取任意一个public修饰的方法信息
    Method run1 =class1.getMethod("run");
    System.out.println(run1);
    System.out.println("------------");
    

     结果:

4、以class1为例进行构造器的获取,构造器一般都是public类型的若有其他类型用getDeclaredConstructors获取。

//4、以class1为例进行构造器的获取,构造器一般都是public类型的若有其他类型用getDeclaredConstructors获取
//①获取所有的构造器
Constructor[] declaredconstructors =class1.getDeclaredConstructors();
System.out.println(Arrays.toString(declaredconstructors));
System.out.println("------------");
//②获取public修饰的构造器
Constructor[] constructors =class1.getConstructors();
System.out.println(Arrays.toString(constructors));
System.out.println("------------");
//③获取任意某个public修饰的构造器
Constructor declaredconstructor =class1.getDeclaredConstructor();
Constructor declaredconstructor1 =class1.getDeclaredConstructor(String.class ,Integer.class);
Constructor declaredconstructor2 =class1.getDeclaredConstructor(String.class,Integer.class ,Character.class ,Double.class ,String.class);
System.out.println(declaredconstructor);
System.out.println(declaredconstructor1);
System.out.println(declaredconstructor2);
System.out.println("------------");

     结果:

5、对构造器的调用。

//5对构造器的调用
// ①public修饰的构造器的使用(以该代码所获取的构造器信息为例 Constructor declaredconstructor1 =class1.getDeclaredConstructor(String.class ,Integer.class))
//创建对象 需要强转
Student student1 = (Student) declaredconstructor1.newInstance("aaa",18);
System.out.println("------------");
// ②private修饰的构造器的调用,但想要使用必须暴力反射,而protected、和不写的不需要暴力反射
Constructor  declaredconstructor4=class1.getDeclaredConstructor(String.class);
declaredconstructor4.setAccessible(true);
Student student2= (Student) declaredconstructor4.newInstance("AAA");
System.out.println("------------");

     结果:

6、对方法的调用(以该代码所获取的构造器信息为例 Constructor declaredconstructor1=class1.getDeclaredConstructor(String.class ,Integer.class))。

// 6对方法的调用(以该代码所获取的构造器信息为例 Constructor declaredconstructor1 =class1.getDeclaredConstructor(String.class ,Integer.class))
//创建该对象  Student student1 = (Student) declaredconstructor1.newInstance("aaa",18);
//①对public修饰方法的调用
Method run2= class1.getDeclaredMethod("run");
run2.invoke(student1);
System.out.println("------------");
//②对private修饰方法的调用 需要暴力反射
Method getAge1= class1.getDeclaredMethod("getAge", int.class);
getAge1.setAccessible(true);
getAge1.invoke(student1,18);
System.out.println("------------");
//③不写修饰的方法的调用
Method aaa1 =class1.getDeclaredMethod("aaa", String.class, Integer.class);
aaa1.invoke(student1,"admin",199);
System.out.println("------------");
//对protected修饰方法的调用
Method haha1=class1.getDeclaredMethod("haha", String.class, int.class);
haha1.invoke(student1,"admin",99);
System.out.println("------------");

     结果:

7、对变量的调用赋值取值操作(以该代码所获取的构造器信息为例Constructordeclaredconstructor1=class1.getDeclaredConstructor(String.class ,Integer.class))。

// 7对变量的调用赋值取值操作(以该代码所获取的构造器信息为例 Constructor declaredconstructor1 =class1.getDeclaredConstructor(String.class ,Integer.class))
        //创建该对象  Student student1 = (Student) declaredconstructor1.newInstance("aaa",18);
        //①给privat修饰的变量赋值,取值操作,需要暴力反射
        Field name=class1.getDeclaredField("name");
        name.setAccessible(true);
        name.set(student1,"admin");
        System.out.println(name.get(student1));
        System.out.println("------------");
        //②其他类型不需要
        Field age=class1.getDeclaredField("age");
        age.set(student1,88);
        System.out.println(age.get(student1));
        System.out.println("------------");
        Field sex=class1.getDeclaredField("sex");
        sex.set(student1,'女');
        System.out.println(sex.get(student1));
        System.out.println("------------");
        Field height=class1.getDeclaredField("height");
        height.set(student1,188.88);
        System.out.println(height.get(student1));

    }
}

     结果:

五、反射的练习。

        练习题:

        获取该类的构造方法来构造对象,获取该类的名称和该类中每一个变量的名称和方法名称,并执行相关方法,给没一个变量赋值,并获取值,执行每一个构造方法、执行相应的方法。

//获取该类的构造方法来构造对象,获取该类的名称和该类中每一个变量的名称和方法名称,并执行相关方法,给没一个变量赋值,并获取值,执行每一个构造方法、执行相应的方法
public class Student {
    private String name;
    private int age;
    private String address;

    public Student(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
    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;
    }
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) throws Exception {
        Class class1=Class.forName("反射练习.Student");
        // 获取并打印类名
        System.out.println("类的名称: " + class1.getName());
        // 获取并打印所有字段(变量)名称
        System.out.println("变量名称为");
        Field[] fields = class1.getDeclaredFields();
        for (Field field : fields) {
            System.out.println( field.getName());
        }
        System.out.println("-----------");
        // 获取并打印所有方法名称(包括继承的方法)
        Method[] methods = class1.getMethods();
        System.out.println("方法名称为");
        for (Method method : methods) {
            System.out.println(  method.getName());
        }
        System.out.println("-----------");
        Constructor declaredconstructor1 =class1.getDeclaredConstructor(String.class ,int.class,String.class);
        Student student1= (Student) declaredconstructor1.newInstance("李四",18,"北京 ");
        Field name=class1.getDeclaredField("name");
        name.setAccessible(true);
        System.out.println(name.get(student1));
        Field age=class1.getDeclaredField("age");
        age.setAccessible(true);
        System.out.println(age.get(student1));
        Field address=class1.getDeclaredField("address");
        address.setAccessible(true);
        System.out.println(address.get(student1));
        System.out.println("-----------");
        Method setname= class1.getDeclaredMethod("setName", String.class);
        setname.invoke(student1,"张三");
        Method getname= class1.getDeclaredMethod("getName");
        getname.invoke(student1);
        Method setAge= class1.getDeclaredMethod("setAge", int.class);
        setAge.invoke(student1,20);
        Method getAge= class1.getDeclaredMethod("getAge");
        getAge.invoke(student1);
        Method setaddress= class1.getDeclaredMethod("setAddress", String.class);
        setaddress.invoke(student1,"上海");
        Method getaddress= class1.getDeclaredMethod("getAddress");
        getaddress.invoke(student1);
        Field name1=class1.getDeclaredField("name");
        name1.setAccessible(true);
        System.out.println(name1.get(student1));
        Field age1=class1.getDeclaredField("age");
        age1.setAccessible(true);
        System.out.println(age1.get(student1));
        Field address1=class1.getDeclaredField("address");
        address1.setAccessible(true);
        System.out.println(address1.get(student1));




    }
}

     结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值