欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java反射

程序员文章站 2022-05-13 09:10:41
...

 

JAVA反射机制定义
  JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

JAVA反射机制主要提供了以下功能: 

1.在运行时判断任意一个对象所属的类

 2.在运行时构造任意一个类的对象
 3.在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法→需要取消Java语言访问检查:Method对象.setAccessible(true)
 4.在运行时调用任意一个对象的方法(*****注意:前提都是在运行时,而不是在编译时)

在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中

--Class类:代表一个类
--Filed类:代表类的成员变量(属性)
--Method类:代表类的方法
--Constructor类:代表类的构造方法
--Array类:提供了动态创建数组,以及访问数组的元素的静态方法。该类中的所有方法都是静态方法

上面的类,建议大家都看下jdk帮助文档,没有的话可以下载,这样学习对java最有效率...

Class类
     在 java 的Object类中的声明了数个应该在所有的java类中被改写的methods:hashCode(), equals(),clone(),toString(),getClass()等,其中的getClass()返回一个Class 类型的对象。
     Class类十分的特殊,它和一般的类一样继承自Object,其实体用以表达java程序运行时的 class和 interface,也用来表达 enum,array,primitive,Java Types 以及关键字voidClass 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。Class是Reflection起源,针对任何你想探勘的class(类),唯有现为他产生一个Class的对象,才能应用反射机制。

1.在运行时判断任意一个对象所属的类,多种途径为一个类生成对应的Class对象

   1.运用 Class.forName("java.lang.String")

   2.运用 类名.class:String.class

   3.(a)运用类对象.getClass()

      (b)运用类对象.getSuperclass():返回该类对象的父类的Class对象

   4.运用primitive wrapper classes的TYPE语法: 基本类型包装类的TYPE,如:Integer.TYPE
    注意:TYPE的使用,只适合原生(基本)数据类型

2.在运行时构造任意一个类的对象(利用Class对象)

    1.利用默认构造方法:

Class clazz = Class.forName("java.lang.String");

a.Object o = clazz.newInstance();

b.Constructor constructor = clazz.getConstructor();//获取Constructor类对象

Object o = constructor.newInstance();

    2.利用带参数的构造方法(只能使用最后一种方法)

Class clazz = Class.forName("java.lang.String");

Constructor constructor = clazz.getConstructor(String.class);//获取Constructor类对象(传入的是Class对象)

Object o = constructor.newInstance("Hello");

3.判断任意一个类所具有的成员变量和方法

成员变量

getField(String name) 

返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。

getFields() 

返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。

getDeclaredField(String name) 
返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。

getDeclaredFields() 
返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。

方法

与上面成员变量类似。其它的一些重要方法大家可以查看jdk帮助文档,这是官方的文档,效果你懂得...

4.用Java反射机制调用对象的方法
public class InvokeTester {
    public int add(int param1, int param2) {
        return param1 + param2;
    }
 
    public String echo(String msg) {
        return "echo: " + msg;
    }
 
    public static void main(String[] args) throws Exception {
        Class<?> classType = InvokeTester.class;
        Object invokeTester = classType.newInstance();

        //获取InvokeTester类的add()方法
        Method addMethod = classType.getMethod("add", new Class[]{int.class, int.class});
        //调用invokeTester对象上的add()方法
        Object result = addMethod.invoke(invokeTester, new Object[]{new Integer(100), new Integer(200)});
        System.out.println((Integer) result);
 
        //获取InvokeTester类的echo()方法
        Method echoMethod = classType.getMethod("echo", new Class[]{String.class});
        //调用invokeTester对象的echo()方法
        result = echoMethod.invoke(invokeTester, new Object[]{"Hello"});
        System.out.println((String) result);
    }
}	

 


5.动态创建和访问数组
 
java.lang.Array 类提供了动态创建和访问数组元素的各种静态方法。
public class ArrayTester1 {
    public static void main(String args[]) throws Exception {
        Class<?> classType = Class.forName("java.lang.String");
        // 创建一个长度为10的字符串数组
        Object array = Array.newInstance(classType, 10);
        // 把索引位置为5的元素设为"hello"
        Array.set(array, 5, "hello");
        // 获得索引位置为5的元素的值
        String s = (String) Array.get(array, 5);
        System.out.println(s);
    }
}
 
不完善之处,请大家指正,谢谢...