首页 > 编程语言 > 详细

Java 反射

时间:2019-03-14 23:19:04      阅读:173      评论:0      收藏:0      [点我收藏+]

Class类

Java里面有两个不是类,1基本数据类型 2static成员

任何一个类都是java.lang.Class类的实例对象。表达方式如下3种:

1 Class c1= Foo.class; 任何一个类都有一个隐含的static成员变量class

2 Class c2=foo1.getClass();  c1 c2是Foo类的类类型(class type)

3 Class c2=null; c3=Class.forName("类的全称***.Foo");

一个类是Class的一个对象,c1=c2=c3

Class类的构造方法是私有的,不能像普通类一样new一个对象。只有JVM可以创建Class的对象。

可以通过类的类类型创建类的对象,即Foo foo=(Foo)c1.newInstance(); 前提是Foo有无参构造方法

 

动态加载类

动态vs静态加载  即 运行时加载 vs 编译时加载

上面c3的建立方式就是动态加载类。Class.forName("类全称")  然后c3.newInstance();

new是静态加载, 编译时就加载所有可能使用到的类,无论是否真的用。

功能性的类应该尽量使用动态加载。

 

获取类的方法信息

除了所有的类有.class,基本数据类型还有void关键字也有.class 类类型

Class c1=int.Class;

c1.getName(); c1.getSimpleName();//不含包名

Class类的基本API

public class ClassUtil{
  public static void printClassMessage(Object obj){
    Class c=obj.getClass(); //obj的类类型
    System.out.print(c.getName());//类的名称
    

    Method[] ms=c.getMethods();
    //getMethods获得所有public方法,包括继承来的
    //getDeclaredMethods获得所有自己生命的方法,无论访问权限是什么,没有继承的
    for(int i=0;i<ms.length;i++)
    {
      Class returnType=ms[i].getReturnType()
      System.out.print(returnType.getName()+" ");
      System.out.print(ms[i].getName()+"(");
      Class[] paramTypes=ms[i].getParamTypes();
      for(Class c:paramTypes)
      {
        System.out.print(c.getName()+",");
      }
      System.out.println(")");
    }
//===============================================
    Field[] fs=c.getDeclaredFields();
    for(int i=0;i<fs.length;i++)
    {
      Class type=fs[i].getType();
      System.out.print(type.getName()+" ");
      Class name=fs[i].getName();
      System.out.println(name.getName());
    }
//===============================================
    Constructor[] cs=c.getDeclaredConstructors();
    for(Constructor constructor:cs)
    {
      System.out.print(constructor.getName()+"(");
      Class[] params = constructor.getParamTypes();
      for(Class p:params)
        System.out.print(p.getName()+",");
      System.out.println(")");
    }
  }
}

获取类的成员变量信息

成员变量是java.lang.reflect.Field类的对象。

getFields()

getDeclaredFields()

区别同getMethods vs getDeclaredMethods

获取类的构造函数信息

getConstructors()  getDeclaredConstructors() 所有的构造函数(构造函数都是要自己声明的)

构造函数是java.lang.Contructor类的对象。

总之,要先得到类的类类型,在得到类其中的信息。

 

 

 

方法的反射

1 获取类类型

2 获取方法名称+参数列表

method.invoke(对象,参数列表)

public class A(){ public void print(int a, int b){...} } 

A a=new A();

Class c=a.getClass();

Method m = c.getMethod("print",int.class,int.class); //获取方法

  Object o = m.invoke(a,10,20);

  //方法反射: 用m对象来调用print函数,和a.print调用效果一样的!m.invoke返回方法的返回值。这里是null

 

泛型的本质

反射的操作都是编译之后即运行时的操作。

Java中集合的泛型是防止错误输入的,仅在编译阶段有效,绕过编译就无效了。反射嘛无效了就。

ArrayList list1= new ArrayList();

ArrayList<String> list2=new ArrayList<String>();

Class c1=list1.getClass(); Class c2= list2.getClass();  可以试验发现c1==c2 true

Method m=c2.getDeclaredMethods("add", Object.class);

m.invoke(list2, 20);    这里就不报错类型错误了  int是不能自动转为String的

 

Java 反射

原文:https://www.cnblogs.com/pylc/p/10534134.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!