Java-反射


反射是程序的自我分析能力,通过反射可以确定类有哪些方法、有哪些构造方法以及有哪些成员变量。Javay语言提供了反射机制,通过反射机制能够动态读取一个类的信息;能够在运行时动态加载类,而不是在编译期,反射可用于框架开发

它能够从配置文件中读取配置信息动态加载类,创建对象,以及调用方法和成员变量

1.Java反射机制API

Java反射机制API主要是java.lang.Class类和java.lang.reflect包。

1.1Java.lang.Class类

Class类的一个实例表示Java的一种数据类型,包括类、接口、枚举、注解、数组基本数据类型和void。

void是“无类型”,主要用于方法返回值类型的声明,表示不需要返回值。Class没有公有的构造方法,Class实例是由JVM类加载时自动创建。

在Java程序中Class实例可以通过如下代码实现

import org.omg.Messaging.SYNC_WITH_TRANSPORT;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class reflection {
    public static void main(String[] args) {
        //1.通过类型class静态变量
        Class class1 = String.class;
        //2.通过对象的getClass()方法
        String str = "Hello";
        Class class2 = str.getClass();
        //获得int类型Class实例
        Class class3 = int.class;
        //获得Integer类型Class实例
        Class class4 = Integer.class;
        System.out.println("class2类名称" + class2.getName());
        System.out.println("class2类是否为接口" + class2.isInterface());
        System.out.println("class2是否为数组对象" + class2.isArray());
        System.out.println("class2父类名称" + class2.getSuperclass().getName());
        System.out.println("class1基本类型" + class1.isPrimitive());
        System.out.println("class2基本类型" + class2.isPrimitive());
        System.out.println("class3基本类型" + class3.isPrimitive());
        System.out.println("class4基本类型" + class4.isPrimitive());
    }
}
运行结果如下:
"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:63271,suspend=y,server=n -javaagent:C:\Users\FL\.IntelliJIdea2019.1\system\captureAgent\debugger-agent.jar -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar;E:\编程\eclipseJavaCode\IXml\out\production\IXml;E:\编程\eclipseJavaCode\IXml\lib\jaxws-api.jar;E:\编程\eclipseJavaCode\IXml\lib\jaxws-rt.jar;E:\编程\eclipseJavaCode\IXml\lib\jaxws-tools.jar;E:\编程\eclipseJavaCode\IXml\lib\activation.jar;E:\编程\eclipseJavaCode\IXml\lib\FastInfoset.jar;E:\编程\eclipseJavaCode\IXml\lib\gmbal-api-only.jar;E:\编程\eclipseJavaCode\IXml\lib\http.jar;E:\编程\eclipseJavaCode\IXml\lib\jaxb-api.jar;E:\编程\eclipseJavaCode\IXml\lib\jaxb-impl.jar;E:\编程\eclipseJavaCode\IXml\lib\jsr173_api.jar;E:\编程\eclipseJavaCode\IXml\lib\jsr181-api.jar;E:\编程\eclipseJavaCode\IXml\lib\jsr250-api.jar;E:\编程\eclipseJavaCode\IXml\lib\management-api.jar;E:\编程\eclipseJavaCode\IXml\lib\mimepull.jar;E:\编程\eclipseJavaCode\IXml\lib\policy.jar;E:\编程\eclipseJavaCode\IXml\lib\resolver.jar;E:\编程\eclipseJavaCode\IXml\lib\saaj-api.jar;E:\编程\eclipseJavaCode\IXml\lib\saaj-impl.jar;E:\编程\eclipseJavaCode\IXml\lib\stax-ex.jar;E:\编程\eclipseJavaCode\IXml\lib\streambuffer.jar;E:\编程\eclipseJavaCode\IXml\lib\woodstox.jar;E:\编程\eclipseJavaCode\IXml\lib\jaxb-xjc.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2019.1.3\lib\idea_rt.jar" reflection
Connected to the target VM, address: '127.0.0.1:63271', transport: 'socket'
class2类名称java.lang.String
class2类是否为接口false
class2是否为数组对象false
class2父类名称java.lang.Object
class1基本类型false
class2基本类型false
class3基本类型true
class4基本类型false
public boolean equals();
1.2java.lang.reflect包
  • java.lang..reflect包括了反射中用到的类,主要的类说明如下:
  • Constructor类:提供类的构造方法信息。
  • Field类:提供类或接口中成员变量信息
  • Method类:提供类或接口成员方法信息
  • Array类:提供了动态创建和访问Java数组的方法。
  • Modifier类:提供类和成员访问修饰符信息
示例代码如下:
import org.omg.Messaging.SYNC_WITH_TRANSPORT;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class reflection {
    public static void main(String[] args) {
        
        try {
            //动态加载xx类的运行时对象
            Class c = Class.forName("java.lang.String");
            //获取成员方法集合
            Method[] methods = c.getDeclaredMethods();
            //遍历方法集合
            for (Method method : methods) {
                //打印权限修饰符,如public、protected、private
                System.out.print(Modifier.toString(method.getModifiers()));
                //打印返回值类型名称
                System.out.print(" " + method.getReturnType().getName() + " ");
                //打印方法名称
                System.out.println(method.getName() + "();");
                System.out.println("\n");
            }
        } catch (ClassNotFoundException e) {
            System.out.println("找不到指定的类");
        }

    }
}
执行结果
public boolean equals();
public java.lang.String toString();
public int hashCode();
public int compareTo();
public volatile int compareTo();
public int indexOf();
public int indexOf();
2.创建对象
Java反射机制提供另外一种创建对象的方法。Class类提供了一个实例方法。Class类提供了一个实例方法newInstance(),通过该方法可以创建对象。
Class clz = Class.forName("java.lang.String");
String str = (String) clz.newInstance();
2.1调用构造方法
调用方法newInstance()创建对象,这个过程中需要调用构造方法,上面的代码只是调用了String的默认构造方法,如果想调用非默认构造方法,则需要使用Constructor对象,它对应着一个构造方法。获得Constructor对象需要使用Class类的如下方法:
  • Constructor[] getConstructors():返回所有公共构造方法Constructor对象数组。
  • Constructor[] getDeclaredConstructors():返回所有构造方法Constructor对象数组。
  • Constructor getConstructor(Class... parameterTypes):根据参数列表返回公有Constructor对象,参数parameterTypes是Class数组,指定构造方法的参数列表。
  • Constructor getDeclaredConstuctor(Class...parameterTypes):根据参数列表返回一个Constructor对象,对象parameterTypes同上。
实例代码如下:
import org.omg.Messaging.SYNC_WITH_TRANSPORT;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class reflection {
    public static void main(String[] args) {
        try {
            Class clz = Class.forName("java.lang.String");
            //调用默认构造方法
            String str1 = (String)clz.newInstance();
            
            //设置构造方法参数类型
            Class[] params = new Class[1];
            //第一个参数是String
            params[0] = String.class;
            
            //获取与参数对应的构造方法
            Constructor constructor = clz.getConstructor(params);
            //为构造方法传递参数
            Object[] argObject =new Object[1];

            //第一个参数传递的是“Hello”  
            argObject[0] = "Hello";

            //调用非默认构造方法,构造方法第一个参数是String类型
            String str2 = (String) constructor.newInstance(argObject);
            System.out.println(str2);
            
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
执行结果
"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:64608,suspend=y,server=n -javaagent:C:\Users\FL\.IntelliJIdea2019.1\system\captureAgent\debugger-agent.jar -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar;E:\编程\eclipseJavaCode\IXml\out\production\IXml;E:\编程\eclipseJavaCode\IXml\lib\jaxws-api.jar;E:\编程\eclipseJavaCode\IXml\lib\jaxws-rt.jar;E:\编程\eclipseJavaCode\IXml\lib\jaxws-tools.jar;E:\编程\eclipseJavaCode\IXml\lib\activation.jar;E:\编程\eclipseJavaCode\IXml\lib\FastInfoset.jar;E:\编程\eclipseJavaCode\IXml\lib\gmbal-api-only.jar;E:\编程\eclipseJavaCode\IXml\lib\http.jar;E:\编程\eclipseJavaCode\IXml\lib\jaxb-api.jar;E:\编程\eclipseJavaCode\IXml\lib\jaxb-impl.jar;E:\编程\eclipseJavaCode\IXml\lib\jsr173_api.jar;E:\编程\eclipseJavaCode\IXml\lib\jsr181-api.jar;E:\编程\eclipseJavaCode\IXml\lib\jsr250-api.jar;E:\编程\eclipseJavaCode\IXml\lib\management-api.jar;E:\编程\eclipseJavaCode\IXml\lib\mimepull.jar;E:\编程\eclipseJavaCode\IXml\lib\policy.jar;E:\编程\eclipseJavaCode\IXml\lib\resolver.jar;E:\编程\eclipseJavaCode\IXml\lib\saaj-api.jar;E:\编程\eclipseJavaCode\IXml\lib\saaj-impl.jar;E:\编程\eclipseJavaCode\IXml\lib\stax-ex.jar;E:\编程\eclipseJavaCode\IXml\lib\streambuffer.jar;E:\编程\eclipseJavaCode\IXml\lib\woodstox.jar;E:\编程\eclipseJavaCode\IXml\lib\jaxb-xjc.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2019.1.3\lib\idea_rt.jar" reflection
Connected to the target VM, address: '127.0.0.1:64608', transport: 'socket'
Hello
Disconnected from the target VM, address: '127.0.0.1:64608', transport: 'socket'

Process finished with exit code 0

































































全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务