java 反射

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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() +"{\n");  
    //里边的每一个属性  
    for(Field field:fs){  
        sb.append("\t");//空格  
        sb.append(Modifier.toString(field.getModifiers())+" ");//获得属性的修饰符,例如public,static等等  
        sb.append(field.getType().getSimpleName() + " ");//属性的类型的名字  
        sb.append(field.getName()+";\n");//属性的名字+回车  
    }  

    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 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。

 

 

 



















以上是关于java 反射的主要内容,如果未能解决你的问题,请参考以下文章

反射机制入门

反射机制入门

反射机制入门

使用反射在外部JAR / CLASS上调用包含Hibernate事务的方法(Java EE)

为啥我的 Ray March 片段着色器反射纹理查找会减慢我的帧速率?

OpenGL片段着色器不照亮场景