`
wangjie2013
  • 浏览: 168686 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java反射技术

    博客分类:
  • JAVA
阅读更多

java反射技术

 

Last modified:2013-04-06 23:45:44

***************************************

 

获得Class对象的方法:

Person.class:类名.class

new Person().getClass():对象.getClass()

Class.forName("java.lang.String"):Class.forName(完整类名)。(作用:获得类的字节码。有两种情况:如果这个类在内存中,则直接返回;如果内存中没有则通过类加载器加载到虚拟机内存中。以后要得到这个字节码就不用再加载了。在反射中主要使用这种方法,因为在写源程序的时候还不知道类的名字,也就是说我们可以使用一个变量来代替。)

 

一个字节码可以创建出多个实例对象来。

 

Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。 

Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。 

 

只要是类型就对应一个Class实例对象。有九个预定义的Class对象:八个基本类型加一个void(空类型)。

Primitive Data Type:原生数据类型。

 

int.class.isPrimitive():isPrimitive(原始的)是否是基本数据类型。

 

Integer.TYPE:代表他所包装的那个基本数据类型的那份字节码,也就是基本数据类型的 Class对象(int.class)

 

数组不是基本数据类型(Primitive Data Type),是引用类型,判断是否是数组可以使用:isArray();

 

总之,只要是在源程序中出现的类型,都有各自的一份Class实例对象,例如:int[],void,String,int ……

 

反射(Reflect)

反射:就是把java类中的各种成分映射成相应的java类

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

 

通过反射,我们可以得到各个类中相应成分的Class对象。

 

编译时与运行时的区别:

编译时,检查代码的语法错误。不能检查逻辑错误!

运行时,如果代码存在逻辑错误,那么就会报错。

 

Alt+shift+s:快速生成代码。

 

Constructor:

我们可以通过反射创建对象。

String str = new String("abc");

 

String str = 

(String) String.class.getConstructor(StringBuffer.class)

.newInstance(new StringBuffer("abcde"));

 

如果通过空参数的构造方法创建一个对象,还可以通过Class.newInstance()方法。

例如:

String str = 

(String)Class.forName("java.lang.Stirng").newInstance();

 

Field:

获得Field类对象:Field field = pt1.class.getField("字段名");

获得某个实例的字段值:field.get(pt1);

 

getField方法不能获得私有字段,想要获得可以通过getDeclaredField("字段名")(不论该字段可见不可见都能获得该字段的对象)。想要获取字段的值,可以先执行field.setAccessible(ture);然后再get(pt1),这就是所谓的暴力反射。

英文词汇:declared:声明的;Accessible:可接近,可到达;

 

 

  public static void changeChar(Object obj) throws Exception {
      Field[] fields = obj.getClass().getDeclaredFields();//能看见所有的字段,包括私有的。
      for (Field field : fields) {
          if (field.getType() == String.class) {
              field.setAccessible(true);//暴力反射;
              String oldValue = (String) field.get(obj);
              String newValue = oldValue.replace('a', 'b');
              field.set(obj, newValue);
          }
      }
 }

 

对字节码的比较用“==”!当然用equals也可以。但是“==”更加合适!因为是同一份字节码。

 

Method:

方法与对象是没有关系的。我们通过获得方法对象后,再通过这个方法对象调用某个类执行这个方法。也就是先得到这个方法,然后在针对某个对象去调用这个方法。

 

通过反射的方式获得某个字节码里的方法对象,再用这个方法对象去作用于某个对象。 

 

invoke:恳求;

调用方法:

通常:str.charAt(1);

反射:

Method methodCharAt =Class.forName("java.lang.String").getMethod("charAt",int.class);
  methodCharAt.invoke(str,1);
   

 

由方法去调用对象执行该方法。这是面向对象的思维模式,其实只是这个方法对象给str对象发出了一个恳求,请求被执行。之后str对象就发出一个执行该方法的信号。比如:司机刹车,司机其实是踩了刹车板,给汽车发了一个信号,汽车就进行刹车。到底是如何将车停下的,汽车的刹车方法最清楚这里就是方法恳求被执行,对象发出信号执行它!

 

注意:如果Method对象第一个参数为null,说明这个Method对象对应一个静态方法。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics