欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java反射技术

程序员文章站 2022-07-12 13:30:58
...

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对象对应一个静态方法。

相关标签: java 反射 Class