详解Java反射各种应用

Java除了给我们提供在编译期得到类的各种信息之外,还通过反射让我们可以在运行期间得到类的各种信息。通过反射获取类的信息,得到类的信息之后,就可以获取以下相关内容:

  • Class对象
  • 构造器
  • 变量
  • 方法
  • 私有变量与私有方法
  • 注解
  • 泛型
  • 数组

本文也将从上面几个方面来介绍Java反射。本文涉及的所有代码均在反射代码

首先放出一个Java类作为反射的研究对象,类的内容如下:

public abstract class FatherObject implements Runnable{
 public void doSomething(){
 System.out.println("做事情......");
 }
}
public class ExampleObject extends FatherObject{
 public int age = 30;
 public String name = "byhieg";
 private Integer score = 60;
 public void printName(){
 System.out.println(name);
 }
 public int getAge() {
 return age;
 }
 public void setAge(int age) {
 this.age = age;
 }
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public Integer getScore() {
 return score;
 }
 public void setScore(Integer score) {
 this.score = score;
 }
 public ExampleObject(){
 }
 public ExampleObject(String name){
 }
 public ExampleObject(int age,Integer score){
 }
 @Override
 public void doSomething() {
 super.doSomething();
 }
 @Override
 public void run() {
 System.out.println("run......");
 }
}

Class对象

我们应用会用到反射这个知识点,肯定是想要在运行时得到类的信息,根据类的那些信息去做一些特定的操作。那么,首先无疑就是得到类的信息,在JDK中提供了Class对象来保存类的信息。所以,反射的第一步就是得到Class对象。在JDK中提供了两种方式得到Class对象。

第一种,如果编写代码的时候,就知道Class的名字,可以直接用如下方式得到Class对象:

Class exampleObjectClass = ExampleObject.class;

第二种,如果在编写代码的时候,不知道类的名字,但是在运行时的时候,可以得到一个类名的字符串,可以用如下的方式获取Class对象:

Class exampleObjectClass = Class.forName("cn.byhieg.reflectiontutorial.ExampleObject");

注意,此方法需要有2个条件,第一,forName中的字符串必须是全限定名,第二,这个Class类必须在classpath的路径下面,因为该方法会抛出ClassNotFoundException的异常。

获取到这个Class对象之后,就可以得到类的各种信息,开头已经提及了一些信息,下面,说几个没提到的类的信息。

得到类的名字

类的名字有两种方式得到,一种是getName(),一种是getSimpleName()。第一种得到的是全限定名,第二种得到的是这个类的名字,不带包名。看下面的例子:Class对象,已经通过上面的代码得到了。

 String fullClassName = exampleObjectClass.getName();
 String simpleClassName = exampleObjectClass.getSimpleName();
 System.out.println(fullClassName);
 System.out.println(simpleClassName);

结果如下:

cn.byhieg.reflectiontutorial.ExampleObject
ExampleObject

得到类的包名、父类和实现的接口

类的包名和父类,可以通过如下代码得到。

 //得到包信息
 Package aPackage = exampleObjectClass.getPackage();
 System.out.println(aPackage);
 //得到父类
 Class superClass = exampleObjectClass.getSuperclass();
 System.out.println(superClass.getSimpleName());

结果如下:

package cn.byhieg.reflectiontutorial
FatherObject

很显然,得到父类的返回值也是一个Class对象,那么可以利用这个对象得到父类的一些信息,比如判断父类是不是抽象类

System.out.println("父类是不是抽象类 " + Modifier.isAbstract(superClass.getModifiers()));

getModifiers可以得到类的修饰符,从而得到类的修饰符,当然,这个getModifiers不仅仅Class对象可以调用,Method对象可以调用。

可以使用java.lang.reflect.Modifier类中的方法来检查修饰符的类型:

Modifier.isAbstract(int modifiers);
Modifier.isFinal(int modifiers);
Modifier.isInterface(int modifiers);
Modifier.isNative(int modifiers);
Modifier.isPrivate(int modifiers);
Modifier.isProtected(int modifiers);
Modifier.isPublic(int modifiers);
Modifier.isStatic(int modifiers);
Modifier.isStrict(int modifiers);
Modifier.isSynchronized(int modifiers);
Modifier.isTransient(int modifiers);
Modifier.isVolatile(int modifiers);

此外,我们还可以得到父类实现的接口

 //得到接口
 Class[] classes = superClass.getInterfaces();
 System.out.println("父类的接口" + classes[0]);

因为Java类可以实现很多接口,所以用的数组,但在实际使用的时候,需要先判断数组的长度。

下面,重点讲解上述列出来的内容。

构造器

利用Java反射可以得到一个类的构造器,并根据构造器,在运行时动态的创建一个对象。首先,Java通过以下方式获取构造器的实例:

 //构造器
 Constructor[] constructors = exampleObjectClass.getConstructors();
 for (Constructor constructor : constructors){
  System.out.println(constructor.toString());
 }

结果如下:

public cn.byhieg.reflectiontutorial.ExampleObject(int,java.lang.Integer)
public cn.byhieg.reflectiontutorial.ExampleObject(java.lang.String)
public cn.byhieg.reflectiontutorial.ExampleObject()

如果,事先知道要访问的构造方法的参数类型,可以利用如下方法获取指定的构造方法,例子如下:

 Constructor constructor = exampleObjectClass.getConstructor(String.class);
 System.out.println(constructor.toString());

结果显然是:

public cn.byhieg.reflectiontutorial.ExampleObject(java.lang.String)

还可以用如下方式得到另一个构造器

 Constructor constructor = exampleObjectClass.getConstructor(int.class,Integer.class);
 System.out.println(constructor.toString());

此外,如果我们不知道构造器的参数,只能得到所有的构造器对象,那么可以用如下方式得到每一个构造器对想的参数:

 Constructor[] constructors = exampleObjectClass.getConstructors();
 for (Constructor constructor : constructors){
 Class[] parameterTypes = constructor.getParameterTypes();
 System.out.println("构造器参数如下========================");
 for (Class clz : parameterTypes){
  System.out.println("参数类型 " + clz.toString());
 }
 }

结果如下:

构造器参数如下========================

参数类型 class java.lang.String

构造器参数如下========================

参数类型 int

参数类型 class java.lang.Integer

这里,可以看出无参构造方法,是不打印出结果的。基本类型的Class对象和引用类型的Class对象toString()方法是不一样的。

现在,可以根据构造器的各种信息,动态创建一个对象。

 Object object = constructor.newInstance(1,100);
 System.out.println(object.toString());

这个创建对象的方式有2个条件,第一是通过有参构造器创建的,第二,构造器对象必须通过传入参数信息的getConstructor得到。

第一个条件,对于无参构造方法就可以创建的对象,不需要得到构造器对象,直接Class对象调用newInstance()方法就直接创建对象。

第二个条件,构造器对象必须通过exampleObjectClass.getConstructor(String.class);这种形式得到。如果通过getConstructors得到构造器数组,然后调用指定的构造器对象去创建对象在JDK1.8是会错的。但是JDK1.6是正常的。

变量

利用Java反射可以在运行时得到一个类的变量信息,并且可以根据上面讲的方式,创建一个对象,设置他的变量值。首先,通过如下方法,得到所有public的变量:

 Field[] fields = exampleObjectClass.getFields();
 for (Field field : fields){
  System.out.println("变量为: " + field.toString());
 }

结果如下:

变量为: public int cn.byhieg.reflectiontutorial.ExampleObject.age
变量为: public java.lang.String cn.byhieg.reflectiontutorial.ExampleObject.name

很显然,得到的都是public的变量,上述的private的变量score,并没有得到。

和构造器一样的得到方式一样,我们可以指定一个参数名,然后得到指定的变量:

 Field field = exampleObjectClass.getField("age");
 System.out.println("变量为:" + field.toString());

上述的变量的toString方法得到的名字太长,Java对Field类提供了getName的方法,返回类中写的变量名字,上面的代码就可以改成field.getName()。

反射不仅提供了得到变量的方法,还提供了设置变量值的方式。通过如下方法可以对一个动态生成的类,改变其变量值:

 ExampleObject object = ((ExampleObject) constructor1.newInstance("byhieg"));
 System.out.println("原先的age是 " + object.age);
 field.set(object,10);
 System.out.println("更改之后的age是" + object.age);

结果如下:

原先的age是 30
更改之后的age是10

根据上面的代码,得到名字为age的Field对象,然后调用该对象的set方法,传入一个对象与要更改的值,就可以改变该对象的值了。注意,此方法不仅仅对成员变量有用,对静态变量也可以。当然,如果是静态变量,传入null,不用传对象,也是可以的。

方法

Java反射给我们除了给我们提供类的变量信息之外,当然也给我们提供了方法的信息,反射可以让我们得到方法名,方法的参数,方法的返回类型,以及调用方法等功能。

首先,通过如下代码得到方法:

 //输出类的public方法
 Method[] methods = exampleObjectClass.getMethods();
 for (Method method : methods){
  System.out.println("method = "+ method.getName());
 }

和获取变量一样似曾相识的代码,这里直接调用了getName,来得到类中写的方法名。写到这里,大家应该自然想到,Java同样提供了根据参数,得到具体的方法。

 Method method = exampleObjectClass.getMethod("setAge",int.class);
 System.out.println(method.getName());

这里与得到变量不同的是,getMethod方法还需要传入参数的类型信息,反射提供获取方法参数以及返回类型的方法,得到方法参数的例子如下:

 Method method = exampleObjectClass.getMethod("setAge",int.class);
 System.out.println(method.getName());
 for (Class clz : method.getParameterTypes()){
  System.out.println("方法的参数" + clz.getName());
 }

结果如下:

setAge
方法的参数int

得到方法返回类型的例子如下:

System.out.println(method.getReturnType().getName());

结果如下:

void

此外,Java反射支持通过invoke调用得到的方法。例子如下:

method.invoke(exampleObjectClass.newInstance(),1);

invoke第一个参数是这个对象,第二个参数是变长数组,传入该方法的参数。和Field对象同样,对于静态方法同样,可以传入null,调用静态方法。

私有变量与私有方法

上面的方法只能得到public方法和变量,无法得到非public修饰的方法和变量,Java提供了额外的方法来得到非public变量与方法。即通过getDeclaredFields与getDeclaredMethods方法得到私有的变量与方法,同样也支持用getDeclaredField(变量名)与getDeclaredMethod(方法名)的形式得到指定的变量名与方法名。但是这样得到的Field对象与Method对象无法直接运用,必须让这些对象调用setAccessible(true),才能正常运用。之后的方式就可上面讲的一样了。

注解

先写一个包含注解的类:

@MyAnnotation(name="byhieg",value = "hello world")
public class AnnotationObject {
 @MyAnnotation(name="field",value = "变量")
 public String field;
 @MyAnnotation(name="method",value = "方法")
 public void doSomeThing(){
 System.out.println("做一些事情");
 }
 public void doOtherThing(@MyAnnotation(name="param",value = "参数") String param){
 }
}
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
 public String name();
 public String value();
}

Java给我们提供了在运行时获取类的注解信息,可以得到类注解,方法注解,参数注解,变量注解。

与上面获取方式一样,Java提供了2种获取方式,一种是获取全部的注解,返回一个数组,第二种是指定得到指定的注解。

我们以一个类注解为例,讲解以下这两种获取方式。

 Class clz = AnnotationObject.class;
 Annotation[] annotations = clz.getAnnotations();
 Annotation annotation = clz.getAnnotation(AnnotationObject.class);

然后,就可以根据得到的注解进行后续的处理,下面是一个处理的例子:

 for (Annotation annotation : annotations){
   if (annotation instanceof MyAnnotation){
    MyAnnotation myAnnotation = (MyAnnotation)annotation;
    System.out.println("name: " + myAnnotation.name());
    System.out.println("value:" + myAnnotation.value());
   }
  }

上面的类注解使用Class对象调用getAnnotations得到的,方法注解和变量注解是一样的,分别用method对象与field对象调用getDeclaredAnnotations得到注解,没什么多说的。例子看反射代码

参数注解是比较麻烦的一项,获取方式比较得到,第一步,先取得method对象,调用getParameterAnnotations,但是这个返回值是一个二维数组,因为method对象有很多参数,每个参数有可能有很多注解。例子如下:

Method method1 = clz.getMethod("doOtherThing",String.class);
  Annotation[][] annotationInParam = method1.getParameterAnnotations();
  Class[] params = method1.getParameterTypes();
  int i = 0;
  for (Annotation[] annotations: annotationInParam){
   Class para = params[i++];
   for (Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
     MyAnnotation myAnnotation = (MyAnnotation) annotation;
     System.out.println("param: " + para.getName());
     System.out.println("name : " + myAnnotation.name());
     System.out.println("value :" + myAnnotation.value());
    }
   }
  }

泛型

因为Java泛型是通过擦除来实现的,很难直接得到泛型具体的参数化类型的信息,但是我们可以通过一种间接的形式利用反射得到泛型信息。比如下面这个类:

public class GenericObject {
 public List<String> lists;
 public List<String> getLists() {
  return lists;
 }
 public void setLists(List<String> lists) {
  this.lists = lists;
 }
}

如果一个方法返回一个泛型类,我们可以通过method对象去调用getGenericReturnType来得到这个泛型类具体的参数化类型是什么。看下面的代码:

 Class clz = GenericObject.class;
  Method method = clz.getMethod("getLists");
  Type genericType = method.getGenericReturnType();
  if(genericType instanceof ParameterizedType){
   ParameterizedType parameterizedType = ((ParameterizedType) genericType);
   Type[] types = parameterizedType.getActualTypeArguments();
   for (Type type : types){
    Class actualClz = ((Class) type);
    System.out.println("参数化类型为 : " + actualClz);
   }
  }

结果如下:

参数化类型为 : class java.lang.String

步骤有点繁琐,下面一步步解释:

  1. 反射得到返回类型为泛型类的方法
  2. 调用getGenericReturnType得到方法返回类型中的参数化类型
  3. 判断该type对象能不能向下转型为ParameterizedType
  4. 转型成功,调用getActualTypeArguments得到参数化类型的数组,因为有的泛型类,不只只有一个参数化类型如Map
  5. 取出数组中的每一个的值,转型为Class对象输出。

看结果确实得到了泛型的具体的信息。

如果没有一个方法返回泛型类型,那么我们也可以通过方法的参数为泛型类,来得到泛型的参数化类型,如上面类中的setLists方法。例子如下:

 Method setMethod = clz.getMethod("setLists", List.class);
  Type[] genericParameterTypes = setMethod.getGenericParameterTypes();
  for (Type genericParameterType: genericParameterTypes){
   System.out.println("GenericParameterTypes为 : " + genericParameterType.getTypeName());
   if(genericParameterType instanceof ParameterizedType){
    ParameterizedType parameterizedType = ((ParameterizedType) genericParameterType);
    System.out.println("ParameterizedType为 :" + parameterizedType.getTypeName());
    Type types[] = parameterizedType.getActualTypeArguments();
    for (Type type : types){
     System.out.println("参数化类型为 : " + ((Class) type).getName());
    }
   }
  }

执行的结果如下:

GenericParameterTypes为 : java.util.List<java.lang.String>
ParameterizedType为 :java.util.List<java.lang.String>
参数化类型为 : java.lang.String

因为方法的参数为泛型类型的可能不止一个,所以通过getGenericParameterTypes得到是一个数组,我们需要确定每一个元素,是否是具有参数化类型。后续的步骤与上面类似,就不多说了。

如果连方法参数都不带泛型类,那么只剩下最后一种情况,通过变量类型,即用Field类。例子如下:

  Field field = clz.getField("lists");
  Type type = field.getGenericType();
  if (type instanceof ParameterizedType){
   ParameterizedType parameterizedType = ((ParameterizedType) type);
   Type [] types = parameterizedType.getActualTypeArguments();
   for (Type type1 : types) {
    System.out.println("参数化类型 : " + ((Class) type1).getTypeName());
   }
  }

原理和上面的一样,只不过Type对象是通过field.getGenericType(),剩下的操作类似就不多说了。

关于通过反射获取泛型的参数化类型的信息的介绍就到此为止。

数组

Java反射可以对数组进行操作,包括创建一个数组,访问数组中的值,以及得到一个数组的Class对象。

下面,先说简单的,创建数组以及访问数组中的值:在反射中使用Array这个类,是reflect包下面的。

 //创建一个int类型的数组,长度为3
 int[] intArray = (int[])Array.newInstance(int.class,3);
 //通过反射的形式,给数组赋值
  for (int i = 0 ;i < intArray.length;i++){
   Array.set(intArray,i,i + 2);
  }
//通过反射的形式,得到数组中的值
  for (int i = 0 ; i < intArray.length;i++){
   System.out.println(Array.get(intArray,i));
  }

上述就是创建数组,访问数组中的值利用反射方式。

对于得到一个数组的Class对象,简单的可以用int[].class,或者利用Class.forName的形式得到,写法比较奇怪:

 Class clz = Class.forName("[I");
 System.out.println(clz.getTypeName());

结果为:

int[]

这个forName中的字符串,[ 表示是数组,I 表示是int,float就是 F,double就是 D 等等,如果要得到一个普通对象的数组,则用下面的形式:

Class stringClz = Class.forName("[Ljava.lang.String;");

 [ 表示是数组, L 的右边是类名,类型的右边是一个

这种方式获取数组的Class对象实在是太繁琐了。

在得到数组的Class对象之后,就可以调用他的一些独特的方法,比如调用getComponentType来得到数组成员的类型信息,如int数组就是成员类型就是int。

System.out.println(clz.getComponentType().getTypeName());

结果为int

总结

这次,关于反射的各种应用就到此为止,后续可能会有深入的知识讲解。具体的代码可以去看反射代码

在src包里面是各种类,在test类里是对这些类的访问。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!

(0)

相关推荐

  • Java学习之反射机制及应用场景介绍

    前言: 最近公司正在进行业务组件化进程,其中的路由实现用到了Java的反射机制,既然用到了就想着好好学习总结一下,其实无论是之前的EventBus 2.x版本还是Retrofit.早期的View注解框架都或多或少的用到Java的反射机制. 什么是Java反射机制? JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的以及动态调用对象的方法的功能称为Java的反射机制. 反射机制提供了哪些功能? 在运行时判定

  • java反射应用详细介绍

    本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案例1]通过一个对象获得完整的包名和类名 复制代码 代码如下: package Reflect; /** * 通过一个对象获得完整的包名和类名 * */ class Demo{ //other codes... } class hello{ public static void main(String[] args)

  • 应用Java泛型和反射导出CSV文件的方法

    本文实例讲述了应用Java泛型和反射导出CSV文件的方法.分享给大家供大家参考.具体如下: 项目中有需求要把数据导出为CSV文件,因为不同的类有不同的属性,为了代码简单,应用Java的泛型和反射,写了一个函数,完成导出功能. 复制代码 代码如下: public <T> void saveFile(List<T> list, String outFile) throws IOException {         if (list == null || list.isEmpty())

  • 详解Java编程中的反射在Android开发中的应用

    反射定义 "反射"(Reflection)能够让运行于JVM中的程序检测和修改运行时的行为. 为何需要反射 反射带来的好处包括: 在运行时检测对象的类型. 动态构造某个类的对象. 检测类的属性和方法. 任意调用对象的方法. 修改构造函数.方法.属性的可见性. 反射方法Method getDeclaredMethod方法 声明如下: public Method getDeclaredMethod(String name, Class<?>... parameterTypes)

  • Java反射学习 getClass()函数应用

    Java反射学习 所谓反射,可以理解为在运行时期获取对象类型信息的操作.传统的编程方法要求程序员在编译阶段决定使用的类型,但是在反射的帮助下,编程人员可以动态获取这些信息,从而编写更加具有可移植性的代码.严格地说,反射并非编程语言的特性,因为在任何一种语言都可以实现反射机制,但是如果编程语言本身支持反射,那么反射的实现就会方便很多. 1,获得类型类 我们知道在Java中一切都是对象,我们一般所使用的对象都直接或间接继承自Object类.Object类中包含一个方法名叫getClass,利用这个方

  • 详解JAVA 反射机制

    什么是反射? 反射机制是在程序运行状态中,对于任意一个类,都能够获取这个类的所有属性和方法: 对于任意一个对象,都能够调用它的任意一个方法和属性: 这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制. 反射的作用 1.可以实现简单的反编译,获取类中的属性和方法等基本信息,.class->java 2.通过反射机制获取类的属性.方法等 在使用eclipse时,通过对象引用.的方式,eclipse就会将这个对象中的所有属性和方法展示出来,这个就是利用的反射机制.其实反射应用最多的

  • 详解Java 反射和反射的应用场景

    反射机制介绍 JAVA 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为 java 语言的反射机制. 获取 Class 对象的两种方式 如果我们动态获取到这些信息,我们需要依靠 Class 对象.Class 类对象将一个类的方法.变量等信息告诉运行的程序.Java 提供了两种方式获取 Class 对象: 1.知道具体类的情况下可以使用: Class alunbarCla

  • 详解Java反射创建对象

    一.什么是反射 Java Reflaction in Action中的解释:反射是运行中的程序检查自己和软件运行环境的能力,它可以根据它发现的进行改变.通俗的讲就是反射可以在运行时根据指定的类名获得类的信息 个人理解:就是我们对于创建对象我们除了通过 new关键字创建外,还能通过什么创建呢?private的属属性真的不能获取吗?反射就能做到打破这些所谓的规则反射和new创建对象谁的效率高? new 二.通过类对象调用newInstance()方法,适用于无参构造方法 2.1 类名.class p

  • 详解Java反射各种应用

    Java除了给我们提供在编译期得到类的各种信息之外,还通过反射让我们可以在运行期间得到类的各种信息.通过反射获取类的信息,得到类的信息之后,就可以获取以下相关内容: Class对象 构造器 变量 方法 私有变量与私有方法 注解 泛型 数组 本文也将从上面几个方面来介绍Java反射.本文涉及的所有代码均在反射代码 首先放出一个Java类作为反射的研究对象,类的内容如下: public abstract class FatherObject implements Runnable{ public v

  • 图文详解java反射机制及常用应用场景

    目录 一.什么是java反射? 二.HelloWorld 三.类加载与反射关系 四.操作反射的java类 4.1.获取Class对象的三种方法 4.2.获取Class类对象的基本信息 4.3.获得Class对象的成员变量 4.4.获取Class对象的方法 4.5.方法的调用 4.6.创建类的对象(实例化对象) 五.反射的常用场景 5.1.通过配置信息调用类的方法 5.2.结合注解实现特殊功能 5.3.按需加载jar包或class 六.反射的优缺点 一.什么是java反射? 在java的面向对象编

  • 详解Java反射实现Aop代理

    利用反射生成JDK的动态代理,也就是AOP中的AOP代理,代替目标对象,从而在代码中织入增强. 定义代理接口 由于JDKf动态代理只能为接口创建动态代理,故先定义接口,假定我们需要对数据的Save方法添加事务处理,我们有一个UserDao接口,里面有一个Save方法,代码如下: public interface UserDao { public void save(); } 定义代理实现 下面具体来实现接口定义的Save方法,我们采用下面的代码来实现. public class UserDaoI

  • 详解java中反射机制(含数组参数)

    详解java中反射机制(含数组参数) java的反射是我一直非常喜欢的地方,因为有了这个,可以让程序的灵活性大大的增加,同时通用性也提高了很多.反射原理什么的,我就不想做过大介绍了,网上一搜,就一大把.(下面我是只附录介绍下) Reflection 是Java被视为动态(或准动态)语言的一个关键性质.这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等等).superclass(例如O

  • 详解Java高级特性之反射

    定义 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制. 用途 在日常的第三方应用开发过程中,经常会遇到某个类的某个成员变量.方法或是属性是私有的或是只对系统应用开放,这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或是方法.当然,也不是所有的都适合反射,之前就遇到一个案例,通过反射得到的结果与预期不符.阅读源码发现,经过层层调用后在

  • Java 类型信息详解和反射机制介绍

    RTTI RTTI(RunTime Type Information)运行时类型信息,能够在程序运行时发现和使用类型信息,把我们从只能在编译期知晓类型信息并操作的局限中解脱出来 传统的多态机制正是 RTTI 的基本使用:假设有一个基类 Shape 和它的三个子类 Circle.Square.Triangle,现在要把 Circle.Square.Triangle 对象放入 List<Shape> 中,在运行时,先把放入其中的所有对象都当作 Object 对象来处理,再自动将类型转换为 Shap

  • 详解Java中的反射机制和动态代理

    一.反射概述 反射机制指的是Java在运行时候有一种自观的能力,能够了解自身的情况为下一步做准备,其想表达的意思就是:在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功能就称为java语言的反射机制.通俗点讲,通过反射,该类对我们来说是完全透明的,想要获取任何东西都可以,这是一种动态获取类的信息以及动态调用对象方法的能力. 想要使用反射机制,就必须要先获取到该类

随机推荐