JAVA反射其实就是那么一回事

Posted Answer.AI.L

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA反射其实就是那么一回事相关的知识,希望对你有一定的参考价值。

概念:什么是反射

  java反射机制: JAVA反射机制是在运行状态中,

          对于任意一个类,都能够知道这个类的所有属性和方法;

          对于任意一个对象,都能够调用它的任意一个方法和属性;

         这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

  简而言之: 就是根据一个已经实例化了的对象来还原类的完整信息

 

案例1:通过反射修改属性

package Test2016.demo;

import java.lang.reflect.Field;

public class Demo4 {

    public static void main(String[] args) throws Exception {
        
        Student stu = new Student();

        Field[] fields = stu.getClass().getDeclaredFields();
        
        for (Field f : fields) {
            f.setAccessible(true);  //设置是否允许访问,不写运行会报错
            
            if (f.getName() == "name") {
                f.set(stu, "java");
            } else if (f.getName() == "age") {
                f.set(stu, 20);
            }
        }
        System.out.println(stu);    //输出:java:20
    }
}


class Student {
    
    private String name;
    
    private int age;
    
    public Student() {
        this.name = "zhangsan";
        this.age = 10;
    }
    
    //重写toString方法,否则输出:Test2016.demo.Student@e53108
    public String toString() {
        return this.name + ":" + this.age;
    }
}

 

案例2:通过反射调用方法

package Test2016.demo;

import java.lang.reflect.Method;


public class Demo4 {

    @SuppressWarnings("unchecked")
    public static void main(String[] args) throws Exception {
        
        Student stu = new Student("zhangsan", 21);
        
        Class c = stu.getClass();
        
        //getMethod()方法需要传入方法名和方法所带参数的参数类型
        Method method = c.getMethod("score", int.class);
        
        //invoke()表示调用的意思,需要传入对象和参数
        method.invoke(stu, 100);
        
        Method m = c.getMethod("say", String.class);
        //这里的null表示不由对象调用,也就是静态方法,把null换位stu也是可行的
        m.invoke(null, "hello java!!!");
    }
}


class Student {
    
    private String name;
    
    private int age;
    
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public void score(int score) {
        System.out.println(this.name + " 考了 " + score + " 分");
    }
    
    public static void say(String str) {
        System.out.println("刚才我说了:" + str);
    }
    
    @Override
    public String toString() {
        return this.name + "-" + this.age;
    }
}

 程序输出:  zhangsan 考了 100 分
       刚才我说了:hello java!!!

 

案例3:通过反射操作数组

package Test2016.demo;

import java.lang.reflect.Array;


public class Demo4 {

    public static void main(String[] args) throws Exception {
        
        int[] arr = {1, 2, 3, 4, 5};
        
        //getComponentType()返回你数组里面装的数据的数据类型的类名称。这里也就是int
        Class<?> c = arr.getClass().getComponentType();    
        
        System.out.println("数组类型:" + c.getName());    //数组类型:int
        
        int len = Array.getLength(arr);
        System.out.println("数组长度:" + len);    //数组长度:5
        
        System.out.print("遍历数组:");
        
        for (int i = 0; i < len; i++) {
            System.out.print(Array.get(arr, i) + " ");    //遍历数组:1 2 3 4 5 
        }
        
        System.out.println();
        
        System.out.println("修改第三个数据前:" + Array.get(arr, 2));    //修改第三个数据前:3
        Array.set(arr, 2, 10);
        System.out.println("修改第三个数据后:" + Array.get(arr, 2));    //修改第三个数据后:10
    }
}

 注意点: 

  getFields()与getDeclaredFields()区别:

    getFields()只能访问类中声明为公有的字段,私有的字段它无法访问,能访问从其它类继承来的公有方法.

    getDeclaredFields()能访问类中所有的字段,与public,private,protect无关,不能访问从其它类继承来的方法  

   getMethods()与getDeclaredMethods()区别:

    getMethods()只能访问类中声明为公有的方法,私有的方法它无法访问,能访问从其它类继承来的公有方法.

    getDeclaredFields()能访问类中所有的字段,与public,private,protect无关,不能访问从其它类继承来的方法  

   getConstructors()与getDeclaredConstructors()区别:

    getConstructors()只能访问类中声明为public的构造函数.

    getDeclaredConstructors()能访问类中所有的构造函数,与public,private,protect无关 

    

以上是关于JAVA反射其实就是那么一回事的主要内容,如果未能解决你的问题,请参考以下文章

程序集和反射(C#)

java 反射代码片段

反射机制

反射机制

其实吧,LRU也就那么回事。

Java核心技术梳理-类加载机制与反射