您的位置:首页 > 编程语言 > Java开发

Java反射

2015-07-17 13:45 633 查看
1、Class类

       Java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class。

       得到各个字节码对应对应的实例对象(Class类型)的方法有三种:

          (a)类名.class,例如:System.class

          (b)对象.getClass(),例如:new Date().getClass();

          (c)Class.forName("类名"),例如:Class.forName("java.util.Date");
String str1="abc";
Class cls1=str1.getClass();
Class cls2=String.class;
Class cls3=Class.forName("java.lang.String");
System.out.println(cls1==cls2);//true
System.out.println(cls1==cls3);//true
System.out.println(int.class==Integer.class);//false
System.out.println(int.class==Integer.TYPE);//true
System.out.println(int.class.isPrimitive());//true  基本数据类型的Class实例对象可以用Class.isPrimitive()方法来判断
System.out.println(int[].class.isArray());//true 数组类型的Class实例对象可以用Class.isArray()方法来判断
      总之,只要是在源程序中出现的类型,都有格子的Class实例对象,例如 int[],void。

2、 反射的概念

       反射就是把Java类中的各种成分映射成相应的Java类。例如,一个Java类中用一个Class类对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示,就像汽车是一个类,汽车中的发动机、变速箱等等也是一个类。表示Java类的Class类显然要提供一系列的方法,来获得其中的变量、方法,构造方法、修饰符、包等信息,这些信息就是用相应类的实例对象来表示,它们是Field、Method、Contructor、Package等等。

3、 构造方法的反射应用Constructor类

       Constructor类代表某个类中的一个构造方法。

       得到某个类所有构造方法:Constructor[] cons=Class.forName("java.lang.String").getConstructors();

       得到某一个构造方法:Constructor con=Class.forName("java.lang.String").getConstructor(StringBuffer.class);//getConstructor()这里要用到类型

       创建实例对象:

           通常方式  String str=new String(new StringBuffer("abc"));

           反射方式: String str=(String)con.newInstance(new StringBuffer("abc"));

       Class.newInstance()方法:

           示例:String str=(String)Class.forName("java.lang.String").newInstance();

           该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象,用缓存机制来保存默认构造方法的实例对象。

4、 成员变量的反射Field类    

       Field类代表某个类中的一个成员变量,示例如下:
class ReflectPoint{
private int x;
public int y;
public String str1="abc";
     private String str2="basketball";
     public String str3="zrf";
ReflectPoint(int x,int y){
this.x=x;
this.y=y;
}
@Override
    public String toString() {
        return "ReflectPoint [str1=" + str1 + ", str2=" + str2 + ", str3="
                + str3 + "]";
    }
 }
class ReflectTest{
public static void main(String[] args){
ReflectPoint pt1=new Reflectpoint(3,5);
Field fy=pt1.getClass().getField("y"); //fy不代表对象上的变量,而是类上的变量,对于不同的对象其y的值都不同,要用fy去取某个对象上对应的值
System.out.println(fy.get(pt1));//5
//Field fx=pt1.getClass().getField("x");//这句会抛出异常,因为x是私有的,不会让别的类看到
//如果想得到其中的私有成员变量,可以这样操作
Field fx=pt1.getClass().getDeclaredField("x");//此时fx还不能被操作,只是让我们看到有这个成员变量
fx.setAccessible(true);
System.out.println(fx.get(pt1));//3 暴力反射
Field[] fields=pt1.getClass().getFields();//不能得到私有成员变量    
if(fields!=null){        
for(Field f:fields){            
 if(f.getType()==String.class){                
try {                    
f.set(pt1,((String)f.get(pt1)).replace('b', 'a'));                
} catch (IllegalArgumentException | IllegalAccessException e) {                    
 System.out.println("getFields()能看到私有成员变量!");                
 }                               
 }        
}    
}    
System.out.println(pt1);
}
}



5、 成员方法的反射Method类

       Method类代表某个类中的一个成员方法。
String str="abc";
Method methodCharAt=String.class.getMethod("charAt",int.class);
System.out.println(methodCharAt.invoke(str,1));//b  若为静态方法,invoke方法第一个参数设为null
6、 用反射方式执行某个类的main方法

       启动Java程序的main方法的参数是一个字符串数组,即public static void main(String[] args),通过反射调用main方法时,如何为invoke方法传递参数呢?按jdk1.5的语法,整个数组是一个参数,但是按照jdk1.4的语法,数组中的每一个元素对应一个参数,因为要兼容1.4的语法,会把数组打散成若干个单独的参数,因此使用代码 mainMethod.invoke(null,new String[]{"XXX"})会出现参数类型不对问题。

       解决办法如下面代码所示:
Class clazz=Class.forName(args[0]);
Method mainMethod=clazz.getMethod("main",String[].class);
mainMethod.invoke(null,new Object[]{new String[]{"xxx","111"}});
mainMethod.invoke(null,(Object)new String[]{"xxx","111"});//编译器会做特殊处理,不把参数当数组看待,所以不会把参数拆散成若干个参数



7、 数组的反射

        a、具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象

        b、代表数组的Class实例对象的getSuperclass()方法返回的父类为Object类对应的Class

        c、基本类型的一维数组可以看作是Object的子类对象使用,但不可以当作Object[]类型使用;

           非基本类型的一维数组,可以当作Object类型使用,也可以当作Object[]类型使用

      
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: