黑马程序员-反射

来源:互联网 发布:u盘 恢复数据.电脑 编辑:程序博客网 时间:2024/06/05 16:07
------- android培训、java培训、期待与您交流! ----------

反射

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

       一个类中的每一个成员都可以用相应的反射API类的一个实例对象来表示,通过调用Class类的方法可以得到这些实例对象。\

 

字节码:

       每一个类都有一份字节码

Person p1 = new Person();

得到字节码的三种方式:

1.      p1.getClass();

2.      类名.class;   例如:System.class

3.      Class.forName();   括号内是具体的类名

 

Constructor

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

Constructor [] constructor = Class.forName(“java.lang.String”).getConstructors();

//得到String类的所有构造方法

Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);

       //得到String类的一个构造方法

 

创建实例对象

通常用的方法:Stringstr = new String(new StringBuffer(“abc”));

反射: String str= (String) constructor.newInstance(new StringBuffer(“abc”))

调用获得的方法时要用到上面相同类型的实例对象。

Class也有newInstance()方法

       它是先找到无参数的构造方法,然后new对象,该方法内部先得到默认的构造方法,、然后用该构造方法创建实例对象。

String obj = (String) Class.forName(“java.lang.String”).newinstance();

 

Field

       代表某一个类中的一个成员变量

例子:

public class Fieldtest{

       privateint x;

       privateint y;

       publicFieldtest(int x,int y)

       {

              this.x=x;

              this.y=y;

}

}

public class demo{

       publicstatic void main(String []args){

              Fieldtestf1 = new Fieldtest(3,5);

              Fieldfieldy = f1.getClass().getField(“y”);//获取字节码,然后通过字节码获取字段

              System.out.println(fieldy.get(f1));//fieldy不是对象上的变量,而是类上的,要用它去取某个对象上对应的值。

              Fieldfieldx = f1.getClass().getDeclaredField(“x”);//x是私有的,在这里找不到,所以用到DeclaredFieldf()方法找到x

              Fieldx.setAccessible(true);//获得获取x值得权利

              System.out.pritnln(fieldx.get(f1));

                           

       }

}

Method

       代表某一个类中的一个成员方法

String str = “abcd”;

Method method1 = String.class.getMethod(“charAt”,int.class);

//获取方法,通过字节码获取,charAt是要获取的方法,但是charAt有很多类型的参数,这里获取int型,所以后边是类型字节码。

System.out.println(method1.invoke(str,1)); 

 //相当于str.charAt(1);Method对象调用invoke方法实现。

如果invoke(null,1);      //参数(对象)为null,说明该方法是静态方法,不需要对象。

 

mian方法反射

例子:

通常:

public class TestArguments{

       publicstatic void main(String []args){

              for(Stringarg : args)

              {

                     System.out.println(arg);

}    

       }

}

TestArguments.main(new String[]{“111”,”222”,”333”});

反射:

String startclassname = args[0];

Method mainmethod =Class.forName(startclassname).getMethod(“main”,String[].class);

Mainmethod.invoke(null,new Object[]{newString []{“111”,”222”,”333”}});

              //要传进来的是一个String类型的数组而new String []{“111”,”222”,”333”}会自动拆包,就相当于传进来三个参数,编译会出错,所以用newObject[]{}包装起来。也可以通过类型转换的方式:mianmethod.invoke(null,(Object)new String[]{“111”,”222”,”333”});,编译时就不会把参数当做是数组。

数组的反射:

       Array工具类用于完成对数组的反射操作

例子:

是数组就把数组拆开打印,不是直接打印。

public static void printobject(Object obj){

       classclazz = obj.getClass();

if(clazz.isArray())

{

       Int len = Array.getlength(obj);

       for(int i=0;i<len;i++)

       {

              System..out.println(Array.get(obj,i));

}

}

else

{

       System.out.println(obj);

}

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

 

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

 

基本类型的一维数组可以被当做Object类型使用,不能当做Object[]类型使用;非基本类型的一维数组既可以当做Object类型使用,也可以当做Object[]类型使用。

例子:

int [] a1 = new int[3];

int [] a2 = new int[4];

int [][]a3 = new int[2][3];

String []a4 = new String[3];

a1.getClass()==a2.getClass()返回true

a1.getClass()==a4.getClass()返回false;

a1.getClass()==a3.getClass()返回false;

原创粉丝点击