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

时间:2024-09-11 22:35:56

概念:什么是反射

  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无关

    

相关文章