Java基础--反射

目录

一、什么是反射

二、反射的工作流程

三、用法

1、获取变量信息

2、获取方法信息

3、获取构造器信息

4、创建对象

5、调用方法

6、调用变量(get set)


一、什么是反射

反射:能够获取类信息的能力叫做反射

        Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到类对象之后,再通过类对象进行反编译,从而获取对象的各种信息。

        Java属于先编译再运行的语言,程序中对象的类型在编译期就确定下来了,而当程序在运行时可能需要动态加载某些类,这些类因为之前用不到,所以没有被加载到JVM。通过反射,可以在运行时动态地创建对象并调用其属性,不需要提前在编译期知道运行的对象是谁。

二、反射的工作流程

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

通过代码我们可以看到类信息在同一个地方

想要获取类信息就必须进入类对象阶段

三、用法

1、获取变量信息

getDeclaredFields()与getFields()      多个

getDeclaredField()与getField()          单个

加declare和不加的区别:加了declare能找到全部,不加declare仅能找到public修饰的

举例:创建student类

public class Student {
    private String name = "nihao";
    public int age;
    Character sex = '男';
    protected Double height = 180.0;
    public String color = "blue";
}

测试类

public class Test {
    public static void main(String[] args) throws Exception {
        Class class1 = Class.forName("反射.Student");

        //获取全部全局变量的信息,并打印
        Field[] files = class1.getDeclaredFields();
        System.out.println(Arrays.toString(files));
        //获取public修饰的全局变量信息,并打印
        Field[] files1 = class1.getFields();
        System.out.println(Arrays.toString(files1));

        System.out.println("------------------------");
        //加declare
        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);
        //不加declare
        Field nameField1 =class1.getField("name");
        System.out.println(nameField1);        //报错,pirvate不能访问
        Field heightField1 = class1.getField("height");
        System.out.println(heightField1);       //报错,protected不能访问
        Field ageField1 = class1.getField("age");
        System.out.println(ageField1);           //正确
    }
}

 运行结果

2、获取方法信息

getDeclaredMethods()与getMethods()

getDeclaredMethod()

测试类

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));

        Method[] methods = class1.getMethods();    //包括了父类object类当中public修饰的方法
        System.out.println(Arrays.toString(methods));

        Method getage = class1.getDeclaredMethod("getage", int.class);
        System.out.println(getage);
        Method aaa = class1.getDeclaredMethod("aaa", String.class, Integer.class);
        System.out.println(aaa);
        Method run = class1.getDeclaredMethod("run");
        System.out.println(run);
        Method hhh = class1.getDeclaredMethod("haha", String.class, int.class);

        Method run1 = class1.getMethod("run");
        System.out.println(run1);
    }
}

运行结果

 

3、获取构造器信息

getDeclaredConstructors()与getConstructors()

getDeclaredConstructor()

public class Test {
    public static void main(String[] args) throws Exception {
        Class class1 = Class.forName("反射.Student");
        //获取public
        Constructor[] constructors = class1.getConstructors();
        System.out.println(Arrays.toString(constructors));
        //获取全部
        Constructor[] declareconstructors = class1.getDeclaredConstructors();
        System.out.println(Arrays.toString(declareconstructors));
        //单个获取,输入参数列表
        Constructor a0 = class1.getDeclaredConstructor();    //
        System.out.println(a0);    //获取无参构造器
        Constructor a1 = class1.getDeclaredConstructor(String.class,Integer.class);
        System.out.println(a1);   //获取有string和integer的构造器
        Constructor a2 = class1.getDeclaredConstructor(String.class,Integer.class, Character.class, Double.class, String.class);
        System.out.println(a2);    //获取
    }
}

 运行结果

 

4、创建对象

newInstance(参数)

public static void main(String[] args) throws Exception {
    Class class1 = Class.forName("反射.Student");
    Constructor declaredconstructor = class1.getDeclaredConstructor(String.class,Integer.class);
    //创建对象
    Student student = (Student) declaredconstructor.newInstance("aaa",18);
    
    Constructor declaredconstructor1 = class1.getDeclaredConstructor();
    //private修饰的变量想要使用必须暴力反射
    declaredconstructor1.setAccessible(true);
    Student student2 = (Student) declaredconstructor1.newInstance();
    }
}

 

5、调用方法

先获取方法,在调用方法(需要有对象)

方法名.invoke(对象,参数)

调用private方法需要暴力反射          .setAccessible(true);

创建student类

public class Student {
    private String name = "nihao";
    public Integer age;
    Character sex = '男';
    protected Double height = 180.0;
    public String color = "blue";
  //方法
    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()");
    }
}

测试类

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 student = (Student) declaredconstructor.newInstance("aaa",18);
        Method run = class1.getDeclaredMethod("run");
        run.invoke(student);

        Method getage = class1.getDeclaredMethod("getage", int.class);
        getage.setAccessible(true);
        getage.invoke(student,18);

        Method aaa = class1.getDeclaredMethod("aaa", String.class, Integer.class);
        aaa.invoke(student,"admin",1999);

        Method haha = class1.getDeclaredMethod("haha", String.class, int.class);
        haha.invoke(student,"admin",19);
        }
}

运行结果

6、调用变量(get set)
public static void main(String[] args) throws Exception {
    Class class1 = Class.forName("反射.Student");
    Constructor declaredconstructor = class1.getDeclaredConstructor(String.class,Integer.class);
    //创建对象
    Student student = (Student) declaredconstructor.newInstance("aaa",18);
    //private需要暴力反射
    Field name = class1.getDeclaredField("name");
    name.setAccessible(true);
    name.set(student,"李四");
    System.out.println(name.get(student));

    Field age = class1.getDeclaredField("age");
    age.set(student,88);
    System.out.println(age.get(student));

    Field sex = class1.getDeclaredField("sex");
    sex.set(student,'女');
    System.out.println(sex.get(student));

    Field height = class1.getDeclaredField("height");
    height.set(student,179.9);
    System.out.println(height.get(student));
}

运行结果

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值