zoukankan      html  css  js  c++  java
  • Java 反射机制

    Java反射机制:

      参考博客:http://www.cnblogs.com/bojuetech/p/5896551.html

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

    Class:描述类本身的类

      Class是一个类,一个描述类的类(即描述类本身),封装了 描述方法的Method,描述字段的Field,描述构造器的Contstructor等属性

      对象反射可以得到的信息:某个类的数据成员名、方法和构造器、类实现的接口

      对于每个类而言,JRE都为其保留一个不变的Class类型的对象,一个Class对象包含了特定某个类的有关信息

      Class对象只能由系统建立对象

      一个类在JVM中只会有一个Class实例

    反射机制获取类有三种方法:

      直接通过类名.class

    clazz = Person.class;  

      通过对象的getClass()方法获取

        Object obj = new Person();  
        clazz = obj.getClass();  

      通过全类名获取,但可能抛出ClassNotFoundException异常

    clazz = Class.forName("com.java.reflection.Person");  

    clazz使用newInstance创建对象:

      使用Class类的newInstance()创建类的一个对象

      实际调用的是类的无参构造器(所以写类的时候,要写一个无参的构造器)

    Class clazz = Class.forName("com.java.reflection.Person");  
      
    Object obj = clazz.newInstance();  

    ClassLoader加载器:

      类加载器是用于将类装入JVM的

      JVM有两种类型的类加载器:启动类加载器(bootstrap)和用户自定义加载器(user-defined class loader)

      JVM运行时会产生3个类加载器组成的初始化加载器层次结构:

    public void testClassLoader1() throws ClassNotFoundException, IOException {  
        //1、获取一个系统的类加载器  
        ClassLoader classLoader = ClassLoader.getSystemClassLoader();  
        System.out.println("系统的类加载器-->" + classLoader);  
      
        //2、获取系统类加载器的父类加载器(扩展类加载器(extensions classLoader))  
        classLoader = classLoader.getParent();  
        System.out.println("扩展类加载器-->" + classLoader);  
      
        //3、获取扩展类加载器的父类加载器  
        //输出为Null,无法被Java程序直接引用  
        classLoader = classLoader.getParent();  
        System.out.println("启动类加载器-->" + classLoader);  
      
      
        //4、测试当前类由哪个类加载器进行加载 ,结果就是系统的类加载器  
        classLoader = Class.forName("com.java.reflection.Person").getClassLoader();  
        System.out.println("当前类由哪个类加载器进行加载-->"+classLoader);  
      
        //5、测试JDK提供的Object类由哪个类加载器负责加载的  
        classLoader = Class.forName("java.lang.Object").getClassLoader();  
        System.out.println("JDK提供的Object类由哪个类加载器加载-->" + classLoader);  
    }  

     Method:对应类中的方法

        Class clazz = Class.forName("com.java.reflection.Person");  
      
        //1、得到clazz 对应的类中有哪些方法,不能获取private方法  
        Method[] methods = clazz.getMethods();  
        System.out.print("
    getMethods: ");  
        for (Method method : methods){  
            System.out.print(method.getName() + ", ");  
        }  
      
        //2、获取所有的方法(且只获取当着类声明的方法,包括private方法)  
        Method[] methods2 = clazz.getDeclaredMethods();  
        System.out.print("
    getDeclaredMethods: ");  
        for (Method method : methods2){  
            System.out.print(method.getName() + ", ");  
        }  
      
        //3、获取指定的方法  
       //第一个参数是方法名,后面的是方法里的参数
    Method method = clazz.getDeclaredMethod("setName",String.class); System.out.println(" method : " + method);
       //第一个参数是方法名,后面的是方法里的参数 Method method2
    = clazz.getDeclaredMethod("setName",String.class ,int.class); System.out.println("method2: " + method2); //4、执行方法! Object obj = clazz.newInstance(); method2.invoke(obj, "draco", 17);

    Methos.invoke()方法:调用Method对象表示的底层方法

    public Object invoke(Object obj,
                         Object... args)
                  throws IllegalAccessException,
                         IllegalArgumentException,
                         InvocationTargetException

      obj:调用底层方法的对象(调用谁的方法就是用谁的对象)

      args:方法调用的参数

    Field字段:

     Class clazz = Class.forName("com.java.reflection.Person");  
      
        //1、获取字段  
        //1.1 获取Field的数组,私有字段也能获取  
        Field[] fields = clazz.getDeclaredFields();  
        for (Field field: fields) {  
            System.out.print(field.getName() + ", ");  
        }  
      
        //1.2 获取指定名字的Field(如果是私有的,见下面的4)  
        Field field = clazz.getDeclaredField("name");  
        System.out.println("
    获取指定Field名=: " + field.getName());  
      
        Person person = new Person("draco", 17); 
    //2、获取指定对象的Field的值 Object val = field.get(person); System.out.println("获取指定对象字段'name'的Field的值=: " + val); //3、设置指定对象的Field的值 field.set(person, "harry"); System.out.println("设置指定对象字段'name'的Field的值=: " + person.name); //4、若该字段是私有的,需要调用setAccessible(true)方法 Field field2 = clazz.getDeclaredField("age"); field2.setAccessible(true); System.out.println("获取指定私有字段名=: " + field2.getName());

    Constructor:构造器

       String className = "com.java.reflection.Person";  
        Class<Person> clazz = (Class<Person>) Class.forName(className);  
      
        //1.获取Constructor对象  
        Constructor<Person>[] constructors =  
                (Constructor<Person>[]) Class.forName(className).getConstructors();  
      
        for (Constructor<Person> constructor: constructors) {  
            System.out.println(constructor);  
        }  
      
        Constructor<Person> constructor = clazz.getConstructor(String.class, Integer.class);  
        System.out.println("指定的-->" + constructor);  
      
        //2.调用构造器的newInstance()方法创建对象  
        Object obj= constructor.newInstance("ron", 11);  

    Annotation:注解

      Annotation是代码中的特殊标记,可以在编译、类加载、运行时被读取,并执行相应的处理;通过Annotation,程序员可以在不改变原有逻辑的情况下,在源文件中嵌入补充信息

      Annotation可以象修饰符一样被使用,可用于修饰包、类、构造器、方法、参数、成员变量、局部变量的声明,这些信息被保存在Annotation的“name=value”中

      Annotation能用于为程序元素(类、方法、成员变量等)设置元数据

      基本的Annotatio:

        使用时在前面加@

        @override:限定重写父类方法

        @Deprecated:用于表示某个程序元素(类、方法等)已过时

        @SuppressWarnings:抑制编译器警告

      自定义的Annotation:

        使用@interface关键字

        Annotation的成员变量在Annotation定义中以无参数的形式声明,其方法名和返回值定义了该成员的名字和类型

        可以在定义Annotation的成员变量时为其指定初始值,指定成员变量的初始值可以使用default关键字

        没有成员定义的Annotation称为标记,包含成员变量的Annotation称为元数据Annotation

  • 相关阅读:
    前端--页面提交重置功能
    ztree获取当前选中节点子节点id集合的方法(转载)
    sqlserver锁表、解锁、查看销表 (转载)
    解决前端文件修改后浏览器页面未更新的问题
    简单的上传文件
    如何在Eclipse中查看JDK以及JAVA框架的源码(转载)
    设计模式--观察者模式
    WebService 学习
    学习quartz定时
    JS 中AJAX,Fetch,Axios关系
  • 原文地址:https://www.cnblogs.com/roxy/p/7668058.html
Copyright © 2011-2022 走看看