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

    万事万物皆为对象,类也是对象,任何一个类都是Class类的对象。

    class类使用

    假设FOO类是一个对象

    Foo foo = new Foo();

    Class c1就声明了一个Class类的实例对象,但是不能通过new关键字来创建,而是有一下三种方法创建。

    1、Class c1 = Foo.class;//任何一个类都有一个隐含的静态成员变量class,如果Foo已经存在,可以用这种方法来创建Foo的类类型(class type),即Foo类的类类型就是Class类的一个实例对象。
    2、Class c2 = foo.getClass();//如果Foo类的对象foo已经存在,可以通过这种方法来创建Foo类的类类型。
    并且,c1==c2是true的,因为任何一个类只有一个类类型。
    3、Class c3 = null;
    c3 = Class.forName("com.imooc.reflect.Foo");//通过Foo的全称来创建
    可知,c2==c3也是true的。

    而且,可以用类类型来创建Foo的实例对象,如下
    Foo foo1 = (Foo)c1.newInstance();//前提是Foo有无参的构造方法

    动态加载类

    1、静态加载类,是编译时刻加载;动态加载类,是运行时刻加载
    2、new创建对象:是静态加载类,在编译时刻就需要加载所有的【可能使用到的类】。有一个类有问题(如不存在),都不能通过编译,会报错。
    3、Class.forName()通过动态加载类,可以用到一个类时,才进行加载。

    编译时加载的类:静态加载类(用new关键词创建的类)
    运行时加载的类:动态加载类(用类类型创建的类)(不过需要有接口或者父类(抽象类))
    //Class.forName("类的全名")
    Class c = Class.forName(args[0]);
    OfficeAble oa = (OfficeAble) (c.newInstance());//需要有无参构造器
    //OfficeAble 是接口(interface)

    Class类的常用方法:
    getName() 基本数据类型得到的是类名,引用型得到的是引用全称(java.lang.String)
    getMethods()/getFields(),得到方法/字段的集合,包括父类继承而来的方法/字段,只限 公共的方法/字段。

    getDeclaredMethods()/getDeclaredFields(),得到当前类的方法/字段,不包括父类的,不限公共的还是私有的,

    Method的getReturnType() 得到方法的返回值的类类型
    Method的getParmeterTypes() 得到的是方法参数的类类型

    一、成员变量是java.lang.reflect.Field的对象
    1、Field类封装了关于成员变量的操作
    2、Field[] fs = c.getFields()方法获取所有public的成员变量Field[]信息
    3、c.getDeclaredFields获取的是该类自己声明的成员变量信息
    4、field.getType()获得成员类型的类类型
    5、field.getName()获得成员的名称
    二、构造函数是java.lang.Constructor类的对象
    1、通过Class.getConstructor()获得Constructor[]所有公有构造方法信息
    2、建议getDeclaredConstructors()获取自己声明的构造方法
    3、Constructor.getName():String
    4、Constructor.getParameterTypes():Class[]
    成员变量也是对象,是java.lang.reflect.Field的对象;

    方法反射

    1. 方法名称加参数列表可以唯一确定一个方法
    2. 通过方法对象来实现方法的功能,即把实例对象当成参数传给方法对象

    下面是列子:
    There is a class A:
    class A{void printInfo(String s1, String s2){System.out.println(s1 + s2);}}

    Implement the class:

    A a = new A();
    Class c = a.getClass();
    Method m = c.getMethod("printInfo", String.class, String.class);
    //getMethod方法只能获得public方法
    //getDeclaredMethod方法能获得所有自己声明的方法
    //you can write the above code like following:
    Method m = c.getMethod("printInfo", new Object[]{String.class,String.class});

    Object o = m.invoke(a, "Hello ", "World!");//Here, o = null
    //You can also write like:
    Object o = m.invoke(a, new Object[]{"Hello ","World!"});
    //The above code just like:
    a.printInfo("Hello ","World!");

     反射-泛型本质:反射操作是在运行时刻(编译之后);编译后集合就没有泛型了;泛型只在编译阶段有效,防止错误输入;通过方法反射操作,绕过编译。

    测试:Method m=c.getMethod("add",object.class);m.invoke(list对象,obj);(list.size();可以判断加入进去了)之后不能使用foreach遍历(因为内部参数数据类型不统一,会抛exception)。

  • 相关阅读:
    December 23rd 2016 Week 52nd Friday
    December 22nd 2016 Week 52nd Thursday
    December 21st 2016 Week 52nd Wednesday
    December 20th 2016 Week 52nd Tuesday
    December 19th 2016 Week 52nd Sunday
    December 18th 2016 Week 52nd Sunday
    uva294(唯一分解定理)
    uva11624Fire!(bfs)
    fzu2150Fire Game(双起点bfs)
    poj3276Face The Right Way
  • 原文地址:https://www.cnblogs.com/zyandroid/p/5342204.html
Copyright © 2011-2022 走看看