zoukankan      html  css  js  c++  java
  • java 反射

    1,what?

    反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字, 那么就可以通过反射机制来获得类的所有信息。 

    2,why?

    为了支持框架、和网络构建(版主并没有找到合适介绍的的材料,暂且记下这些)。

    3,how?

    java反射可以做什么?

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

        1,反编译:.class-->.java

         2,通过反射机制访问java对象的属性,方法,构造方法等

      这样好像更容易理解一些,下边我们具体看怎么实现这些功能。

       准备: 方法 

    实例.getClass().getName()
    getClass() 获取当前类;
    getName() 获取类名;
    package net.xsoftlab.baike;
        public class TestReflect {
            public static void main(String[] args) throws Exception {
                TestReflect testReflect = new TestReflect();
                System.out.println(testReflect.getClass().getName());
                // 结果 net.xsoftlab.baike.TestReflect
            }
        }

    (1),获取类,三种方法:

    public class reftest {
        public static void main(String[] args) {
        //第一种方式:
        Class c1 = null;
        try {
            c1 = Class.forName("ref.Ref");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
      System.out.println(c1.getName()
    +"01");
    //第二种方式: //java中每个类型都有class 属性. Class c2 = Ref.class; System.out.println(c2.getName()+"02"); //第三种方式: //java语言中任何一个java对象都有getClass 方法 Class c3 = new Ref().getClass(); //c3是运行时类 (e的运行时类是Employee) System.out.println(c3.getName()+"03"); } }

    tip:在备用方法中我们使用的方法为:

    实例.getClass().getName()

    在验证获取类的3种方法中,我们使用的方法为  getName();     这是因为c1,c2,c3本身就是类;

    若使用c1.getClass().getName();返回的是Class 类的类类型  // 答案为:java.lang.Class01

    另外:方法1知道的关于类的信息较多(路径),

            方法3的特别之处在于实例化了对象,通过getClass()获取了当前的类;

            方法1,2,3的共同之处在于,你必须知道类名;

    (2)实例化对象,方法:newInstance()

     Class c2 = Ref.class; 
        //创建此Class 对象所表示的类的一个新实例  
        try {
            Object o = c2.newInstance();
            //Ref o  =(Ref) c2.newInstance();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    tip: 采用了方法2获取了类;采用了多肽的方式实例化了Ref, 注意newInstance()方法返回的为Object类型;

    (3)获取属性:分为所有的属性和指定的属性:

    常用方法:

        Field getField(String name)//根据变量名得到相应的public变量

        Field[] getFields()//获得类中所以public的方法

        Field getDeclaredField(String name)//根据方法名获得public和非public变量

        Field[] getDeclaredFields()//获得类中所有的public和非public方法 

    3.1遍历所有属性:

        //获取整个类  
        Class c = Class.forName("java.lang.Integer");  
          //获取所有的属性?  
        Field[] fs = c.getDeclaredFields();  
    
        //定义可变长的字符串,用来存储属性  
        StringBuffer sb = new StringBuffer();  
        //通过追加的方法,将每个属性拼接到此字符串中  
        //最外边的public定义  
        sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() +"{
    ");  
        //里边的每一个属性  
        for(Field field:fs){  
            sb.append("	");//空格  
            sb.append(Modifier.toString(field.getModifiers())+" ");//获得属性的修饰符,例如public,static等等  
            sb.append(field.getType().getSimpleName() + " ");//属性的类型的名字  
            sb.append(field.getName()+";
    ");//属性的名字+回车  
        }  
    
        sb.append("}");  
    
        System.out.println(sb); 

    // 讲解一下Modifier

    Modifier 是Java.lang.reflect下的一个类:主要介绍其tosting方法

    static String toString(int mod)     返回描述指定修饰符中的访问修饰符标志的字符串

    **此处猜测:java必定是通过修饰符和mod 对应的方式 查找到string值返回。

    所以:

    Modifier.toString(c.getModifiers())  返回的为类的修饰符;
    c.getSimpleName() 返回类的名称;
    Modifier.toString(field.getModifiers())  返回属性修饰符;


    b,返回指定属性:
    public static void main(String[] args) throws Exception{  
                  
    <span style="white-space:pre">  </span>//以前的方式:  
        /* 
        User u = new User(); 
        u.age = 12; //set 
        System.out.println(u.age); //get 
        */  
                  
        //获取类  
        Class c = Class.forName("User"); 
        //实例化这个类赋给o  
        Object o = c.newInstance(); 
      //获取id属性  
      Field idF = c.getDeclaredField("id");
      
      //打破封装
      idF.setAccessible(true);
       //使用反射机制可以打破封装性,导致了java对象的属性不安全。 //给o对象的id属性赋值"110"
      idF.set(o, "110"); //set //get

    System.out.println(idF.get(o));
    }

    tip: 获取指定的属性,还可以 打破封装赋值;

    此处讲解一下Filed,是Java.lang.reflect下的一个类,

    最主要的方法是:

    get(Object obj)   得到obj里面的value值

    set(Object obj, Object value)   设置obj的value值

    getModifiers() : 获取属性的修饰

    getName() : 获取属性声明时名字

    (4)获取方法、构造方法、接口~

    方法关键字

    含义

    getDeclaredMethods()

    获取所有的方法

    getReturnType()

    获得方法的放回类型

    getParameterTypes()

    获得方法的传入参数类型

    getDeclaredMethod("方法名",参数类型.class,……)

    获得特定的方法

    构造方法关键字

    含义

    getDeclaredConstructors()

    获取所有的构造方法

    getDeclaredConstructor(参数类型.class,……)

    获取特定的构造方法

    父类和父接口

    含义

    getSuperclass()

    获取某类的父类

    getInterfaces()

    获取某类实现的接口

    详解:

     Method getDeclaredMethod(String name, Class... parameterTypes)
              返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
     Method[] getDeclaredMethods()
              返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。

     

  • 相关阅读:
    JQuery常用动画实现函数
    DOM对象和JQuery对象进行转换
    JQuery中的mouseover和mouseenter的区别
    JQuery使用和选择器
    LintCode 11 二叉查找树的搜索区间
    Java IO整理
    JS基础知识——缓动动画
    JS——无缝滚动
    Java GC系列(1):Java垃圾回收简介
    深入理解Java之线程池
  • 原文地址:https://www.cnblogs.com/binggo2020/p/6686314.html
Copyright © 2011-2022 走看看