`
hulianwang2014
  • 浏览: 726198 次
文章分类
社区版块
存档分类
最新评论
  • bcworld: 排版成这样,一点看的欲望都没有了
    jfinal

Java 反射机制(中)

 
阅读更多

6 Private Fields and Methods

6.1 Accessing Private Fields

访问一个私有成员变量,你将需要去调用Class.getDeclaredField(String name)或Class.getDeclaredFields()。相比而言,Class.getField(String name)和Class.getFields()方法仅仅返回公共(public)成员变量。

publicclass PrivateObject {

private String privateString = null;

public PrivateObject(String privateString) {

this.privateString = privateString;

}

}

PrivateObject privateObject = new PrivateObject("ThePrivate Value");

Field privateStringField = PrivateObject.class.

getDeclaredField("privateString");

privateStringField.setAccessible(true);

String fieldValue = (String)privateStringField.get(privateObject);

System.out.println("fieldValue = " +fieldValue);

6.2 Access Private Methods

访问私有方法,可以通过如下方法:

Class.getDeclaredMethod(Stringname,Class[] parameterTypes)

Class.getDeclaredMethods()

而方法

Class.getMethod(Stringname,Class[] parameterTypes)

Class.getMethods()

仅仅返回public方法。

public classPrivateObject {

private String privateString = null;

public PrivateObject(String privateString) {

this.privateString = privateString;

}

private String getPrivateString(){

return this.privateString;

}

}

PrivateObjectprivateObject = new PrivateObject("The Private Value");

MethodprivateStringMethod =PrivateObject.class.getDeclaredMethod("getPrivateString", null);

privateStringMethod.setAccessible(true);

String returnValue =(String)privateStringMethod.invoke(privateObject, null);

System.out.println("returnValue= " + returnValue);

7 Annotation

程序运行的时候,可以访问一个类、方法和成员变量的注释,请看下面的例子。

Class someClass = TheClass.class;

Annotation[] annotations = someClass.getAnnotations();

for(Annotation annotation : annotations){

if(annotation instanceof MyAnnotation){

MyAnnotation myAnnotation = (MyAnnotation) annotation;

System.out.println("name: " + myAnnotation.name());

System.out.println("value: " + myAnnotation.value());

}

}

可以像这样来访问具体指定的类:

ClasssomeClass = TheClass.class;

Annotationannotation = someClass.getAnnotation(MyAnnotation.class);

if(annotationinstanceof MyAnnotation){

MyAnnotation myAnnotation = (MyAnnotation) annotation;

System.out.println("name: " +myAnnotation.name());

System.out.println("value: " +myAnnotation.value());

}

7.1 Method Annotations

请看一下方法注释的例子:

public class TheClass {
 @MyAnnotation(name="someName", value = "Hello World")
 public void doSomething(){}
}

可以像这样访问方法注释:

Method method = ... //obtain method object
Annotation[] annotations = method.getDeclaredAnnotations();
for(Annotation annotation : annotations){
 if(annotation instanceof MyAnnotation){
 MyAnnotation myAnnotation = (MyAnnotation) annotation;
 System.out.println("name: " + myAnnotation.name());
 System.out.println("value: " + myAnnotation.value());
 }
}

像这样访问指定的方法注释:

Method method = ... // obtain method object
Annotation annotation = method.getAnnotation(MyAnnotation.class);

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

7.2 Parameter Annotations

添加参数注释到方法参数声明上去也成为可能。

public class TheClass {
 public static void doSomethingElse(
 @MyAnnotation(name="aName", value="aValue") String parameter){
 }
}

访问方法上的参数注释:

Method method = ... //obtain method object
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
Class[] parameterTypes = method.getParameterTypes();
int i=0;
for(Annotation[] annotations : parameterAnnotations){
 Class parameterType = parameterTypes[i++];
 for(Annotation annotation : annotations){
 if(annotation instanceof MyAnnotation){
 MyAnnotation myAnnotation = (MyAnnotation) annotation;
 System.out.println("param: " + parameterType.getName());
 System.out.println("name : " + myAnnotation.name());
 System.out.println("value: " + myAnnotation.value());
 }
 }
}

7.3 Field Annotations

具体的例子如下:

public class TheClass {
 @MyAnnotation(name="someName", value = "Hello World")
 public String myField = null;
}

访问方法的成员变量:

Field field = ... //obtain field object
Annotation[] annotations = field.getDeclaredAnnotations();

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

}

访问具体的成员变量:

Field field = ... // obtain method object
Annotation annotation = field.getAnnotation(MyAnnotation.class);
if(annotation instanceof MyAnnotation){
 MyAnnotation myAnnotation = (MyAnnotation) annotation;
 System.out.println("name: " + myAnnotation.name());
 System.out.println("value: " + myAnnotation.value());
}

8 泛型(Generics)

8.1 泛型的大拇指反射规则

使用Java泛型典型地归纳为两种不同的情形。

  1. 声明Class/Interface作为参数化
  2. 使用参数化的类

当运行检查一个参数化的类型,像java.util.List,仍旧没有一个方式知道什么类型的参数被初始化了. 在相同的应用程序中,既然这个类型被初始化为各式各样的类型。但是,当你检测声明了使用一个参数类型的方法(method)或是成员变量(field)时, 在运行时刻,你可以看到什么参数类型被参数初始化了。简而言之,你不能看到关于类型本身是什么类型对于运行时刻被初始化,但是你能看到方法和成员变量在哪儿被使用以及被参数化。

8.2 泛型方法返回类型

如何你获得了一个java.lang.reflect.Method对象,获取关于它的泛型返回类型信心成为可能。在参数化的类型中,这不可能是任何方法对象,但是,在类中那是使用参数化的类型。

public class MyClass {

protected List<String> stringList = ...;

pulicList<String> getStringList(){

return this.stringList;

}

}

侦测到getStringList()返回一个List<String>而不是仅仅一个List成为可能。

Method method =MyClass.class.getMethod("getStringList", null);

Type returnType =method.getGenericReturnType();

if(returnType instanceof ParameterizedType){

ParameterizedType type = (ParameterizedType) returnType;

Type[]typeArguments = type.getActualTypeArguments();

for(Type typeArgument : typeArguments){

Class typeArgClass = (Class) typeArgument;

System.out.println("typeArgClass = " + typeArgClass);

}

}

这个片段代码的输出结果"typeArgClass = java.lang.String"。

8.3 泛型方法参数类型

你能够使用Java反射机制来访问泛型类型的参数类型

public class MyClass {

protected List<String> stringList = ...;

pulicvoid setStringList(List<String> list){

this.stringList = list;

}

}

可以像这样来访问方法参数的泛型参数类型:

method = Myclass.class.getMethod("setStringList",List.class);

Type[] genericParameterTypes =method.getGenericParameterTypes();

for(Type genericParameterType :genericParameterTypes){

if(genericParameterType instanceof ParameterizedType){

ParameterizedType aType = (ParameterizedType) genericParameterType;

Type[] parameterArgTypes = aType.getActualTypeArguments();

for(Type parameterArgType : parameterArgTypes){

Class parameterArgClass = (Class) parameterArgType;

System.out.println("parameterArgClass = " +parameterArgClass);

}

}

}

得到的结果: "parameterArgType = java.lang.String".

8.4 泛型的成员变量类型

访问泛型的成员变量类型:

public class MyClass {

public List<String> stringList = ...;

}

Field field =MyClass.class.getField("stringList");

Type genericFieldType =field.getGenericType();

if(genericFieldType instanceofParameterizedType){

ParameterizedType aType = (ParameterizedType) genericFieldType;

Type[] fieldArgTypes = aType.getActualTypeArguments();

for(Type fieldArgType : fieldArgTypes){

Class fieldArgClass = (Class) fieldArgType;

System.out.println("fieldArgClass = " + fieldArgClass);

}

}


9 数组

有时候,在Java反射机制中,运用数组会有点复杂。尤其当你需要获取对于确定类型的数组类型的Class对象,像int[]等. 下文将讨论如何通过Java反射机制来既创建数组也获取他们的类对象。

9.1 类java.lang.reflect.Array

通过Java反射机制运用数组就是使用java.lang.reflect.Array类,不要将它与Java集合中的java.util.Arrays类弄混了,Java集合中数组包含排序数组,转换成对应集合等使用的方法。

创建数组

通过Java反射机制来创建数组,如下所示:

int[] intArray = (int[])Array.newInstance(int.class, 3);

这个代码例子创建了一个int类型的数组,第一个提供的参数int.class指定什么类型将被使用,第二个参数制定了多少个元素应该引用到这个数组中去。

访问数组

使用Java反射机制访问数组中的元素,可以通过方法Array.get(…)和Array.set(…)

int[] intArray = (int[])Array.newInstance(int.class, 3);

Array.set(intArray, 0, 123);

Array.set(intArray, 1, 456);

Array.set(intArray, 2, 789);

System.out.println("intArray[0] = "+ Array.get(intArray, 0));

System.out.println("intArray[1] = "+ Array.get(intArray, 1));

System.out.println("intArray[2] = "+ Array.get(intArray, 2));

输出结果如下:

intArray[0] = 123

intArray[1] = 456

intArray[2] = 789

过去一个数组的类对象

可以使用非反射对象,如下所示:

Class stringArrayClass = String[].class;

使用Class.forName()是不简单的。例如:你可以像这样访问:

Class intArray =Class.forName("[I");

JVM通过这个字母来描述一个int. 这个在左边的“[”它是一个我感兴趣的int数组。对于原始的其他类型这种方式也是行得通的,你需要做的就是稍微地运用不同的标记。

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

一方面应该注意,你不能使用原始的Class.forName()来获取Class对象. 下面的例子会抛出ClassNotFoundException:

Class intClass1 =Class.forName("I");

Class intClass2 =Class.forName("int");

原始通用的获取class对象,可以这样写:

public Class getClass(String className){

if("int" .equals(className)) return int .class;

if("long".equals(className)) return long.class;

...

return Class.forName(className);

}

一旦你已经获取到了一个类型的类对象,便有一个简单的方式获取那个类型的数组对象。这个方案或者正如你称之为工作区将使用满意的类型来创建一个空的数组以及从这个空的数组中获取这个对象。有点诡秘,但是他确实奏效。下面便是它的具体实现。

Class theClass = getClass(theClassName);

Class stringArrayClass =Array.newInstance(theClass, 0).getClass();

确保这个Class对象确实是一个数组,你可以调用Class.isArray()来检测。

Class stringArrayClass =Array.newInstance(String.class, 0).getClass();

System.out.println("is array: " + stringArrayClass.isArray());

获取数组的组件类型

一旦你获得了一个数组的Class对象,你便可以通过Class.getComponentType()方法访问它的组件类型。这个组件类型就是数组中的各数据项的共同类型。例如,一个数组int[]的组件类型是int.class类对象。 String[]数组的组件类型就是Java.lang.String类对象。具体的例子如下所示:

String[] strings = new String[3];

Class stringArrayClass = strings.getClass();

Class stringArrayComponentType =stringArrayClass.getComponentType();

System.out.println(stringArrayComponentType);


10 动态代理

在运行时刻,使用Java反射机制可以创建动态接口的实现。你做的这一点,使用类 java.lang.reflect.Proxy就可以了。这个类的名称就是为什么我把动态接口的实现称作动态代理的原因。出于不同的目的,动态代理能够被使用。例如,数据库连接、事务管理、动态模拟单元测试对象以及其它AOP-like方法拦截的目的。

10.1 创建动态代理

你能够使用Proxy.newProxyInstance()方法创建动态代理,这个方法三个参数。

public static ObjectnewProxyInstance(ClassLoader loader,

Class<?>[]interfaces,

InvocationHandlerh)

1.这个ClassLoader回去” 加载” (“Load”)动态类

2.去实现数组接口类

3.InvocationHandler 转向所有的在代理上的调用

这儿有一个例子。

InvocationHandler handler = newMyInvocationHandler();

MyInterface proxy = (MyInterface)Proxy.newProxyInstance(

MyInterface.class.getClassLoader(),

new Class[] {MyInterface.class },

handler);

运行了这个代码后,这个proxy变量包含一个接口MyInterface的动态代理实现。所有调用对应代理将被转向到handler的一般接口InvocationHandler的实现上来,InvocationHandler 将会被介绍。

调用处理者(InvocationHandler’s)

正如先前提到的,你必须传递一个调用处理者(InvocationHandler)的实现到Proxy.newProxyInstance()方法中。所有的方法调用对应动态代理将被转移到对应这个调用处理者(InvocationHandler)的实现方法。InvocationHandler的接口如下所示:

public interface InvocationHandler{

Object invoke(Object proxy, Method method, Object[] args)

throws Throwable;

}

下面有一个实现例子。

public class MyInvocationHandler implementsInvocationHandler{

public Object invoke(Object proxy①, Method method ②, Object[] args③)throws Throwable {

//do something "dynamic"

}

}

这个代理参数①传递给那个实现了接口的动态代理对象的invoke()方法,大多数情况下,你不必需要这个对象。这个方法②对象传递给invoke()方法,描述了接口对应动态代理实现的方法上。从这个方法对象上,你能够获得方法的名称、属性类型等。当这个在接口的实现方法被调用时,对象③数组包含传递给这个参数的值。注意:在实现上的原生态(int, long, etc)将会被封装在她们相应的对象上。

众所周知的知道使用情况,动态代理至少有如下用处。

  • 数据库连接和事务管理
  • 动态模拟单元测试对象。
  • 依赖注入容器(DI Container)的适配到传统的工厂接口
  • AOP-like 方法拦截

11 动态类加载和重新加载

Java在运行时,动态类加载和重新加载是可能的,可是这不是像你希望的那么容易。

11.1 类加载器(ClassLoader)

在Java应用程序中,所有的类加载使用的是java.lang.ClassLoader的某个子类,动态加载类也因此必须使用一个java.lang.ClassLoader来完成。当一个类被加载,所有它引用的类也会被加载。这个类加载以迭代地模式进行,直到所有的类被加载完成。在应用程序中,可能不是所有的类,非引用的类不会被加载,直到它们被应用的时刻才会被加载。

11.2 类加载器的层次结构

在Java中Class loaders 组织成一个层次结构。当你创建一个新的标准Java类加载器classLoader ,你必须提供给它一个父类的类加载器ClassLoader 。如果一个类加载器被要求加载一个类,他将会要求它的父类加载器去加载它。如果父类加载器没有发现这个类,这个子类(child class)加载器然后尝试去记载它本身。

11.3 类加载

当加载类时,类加载器使用的步骤如下所示:

1.检测是否这个类已经加载

2.如果没有加载,要求父类加载器去加载这个类。

3.如果父类加载器不能够加载这个类,将尝试这在这个类加载器中去加载这个类。

当你实现了一个能够重新加载类的类加载器,这种情况就不按照这个步骤。这个类去加载不必须要父类加载发出加载请求。

11.4 动态类加载

动态加载一个类是很容易的。你所需要去做是获取ClassLoader 和调用它的loadClass()方法。下面有个例子。

public class MainClass {

public static void main(String[] args){

ClassLoader classLoader = MainClass.class.getClassLoader();

try{

Class aClass = classLoader.loadClass("com.jenkov.MyClass");

System.out.println("aClass.getName() = " + aClass.getName());

}catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

11.5 动态类重载

动态类重载有一点更具挑战性。Java构建类加载总是会检测一个类是否之前加载过,重载这个类因此不可能使用Java构建类加载器。为了重载一个类,你不得不实现你自己的ClassLoader子类。即使有一个自定义的ClassLoader的子类,你会有这个挑战。每个加载的类需要被连接起来,使用ClassLoader.resolve()方法完成。这个方法是不可继承的,不能在你的ClassLoader子类中覆盖这个方法。resovle()方法不允许任何给定的ClassLoader实例去两次连接相同的类。因此,每次你想重载一个类,你必须使用一个新的ClassLoader子类的实例。做到这一点是不可能的,但是,当你设计类重载时,有必有知道这一点。

11.6设计类重载

正如先前陈述,你不能重载一个使用曾经已经加载过类的ClassLoader的类。因此,你将不得不重载一个使用不同ClassLoader实例的类。但是,这个操作引起一个新的挑战。

在一个Java应用程序中,每个加载的类是通过它的完全修饰的名字(包名+类名)以及类加载器(ClassLoader)实例加载它。这意味着,一个通过类加载器A加载的类(MyObject),与使用类加载B加载的类(MyObject)不是相同的类。片段代码如下所示:

MyObject object = (MyObject)
 myClassReloadingFactory.newInstance("com.jenkov.MyObject");

在这个代码中,注意这个MyObject如何作为object变量类型被引用。这个导致MyObject类被代码所指定的相同类加载器所加载。如果这个myClassReloadingFactory对象工厂重载MyObject类使用不同的类加载器,你不能将重载MyObject类抛给MyObject类型的object变量。既然这两个MyObject类使用不同的类加载器加载,它们将会被当成不同的类,即使他们有完全相同标识的名称。尝试将一个类的应用抛给其它的类会导致ClassCastException异常。规避这种限制是可能,但是,你将必须以两种方式中的任何一种来修改你的代码。

1.使用接口作为类型变量,仅仅重新加载这个实现类

2.使用超类作为类型变量,仅仅重载一个子类

相应的代码如下所示:

MyObjectInterface object = (MyObjectInterface)
 myClassReloadingFactory.newInstance("com.jenkov.MyObject");
MyObjectSuperclass object = (MyObjectSuperclass)
 myClassReloadingFactory.newInstance("com.jenkov.MyObject");

如果这个类型是变量、接口或是超级类中的任何一种都奏效,当实现类或是超类被重载了,这些方法不能重载类。为了让功能有效运行,你当然需要实现你的类加载器,让这个接口或是超级类被父类加载。当你的类加载器被要求加载MyObject类,它将会要求取加载MyObjectInterface,或是MyObjectSuperclass类,原因是这些类在MyObject类中被引用到。你的类加载器必须指派加载那些类到能够加载包含接口、超类类型变量的相同类加载器。

Java类加载器大体上可以划分为一下分类:

  • 启动类加载器(Bootstrap class loader,第一级加载器)

启动类加载器加载Java核心的类,比如java.lang、java.util等。这些类是Java运行环境的一部分,启动类加载器是本地实现,因此,通过不同的JVMs,它们可能不同()。

  • 扩展类加载器(Extensions Class Loader,第二级加载器)
    JAVA_HOME/jre/lib/ext下包含有扩展于标准核心Java类的jar包。扩展类加载器加载从ext文件夹下加载类,使用系统属性java.ext.dirs,你可以添加目录和jar文件来被扩展类加载器加载。
  • 系统类加载器(System Class Loader,第三级加载器)

使用系统类加载器加载Java类路径(classpath)上有效的Java类。

你可以看到更多类加载器,比如

java.net.URLClassLoader、 java.security.SecureClassLoader等。那些都扩展于java.lang.ClassLoader。

11.7 类加载器实例

上面的类容包含了许多话题,让我们看看一个简单的例子。下面是一个类加载器子类的例子,注意到它指派了类加载对应的父类,除了一个它打算能够重载类外。如果这个类的加载被指派给父类加载器,它随后不能够被加载。记住,一个类仅仅能够被同一个类加载器加载一次。正如先前所说,这个仅仅是一个展示各种基本的类加载器行为的例子。对于你自己的累加载器,它不是一个预备的产品模板。你自己的类加载器可能应该不会受到限制于这个简单的类,而是一个你知道你将会需要去重载的集合类。另外,你可能应该也不会硬编码这个类路径。

public class MyClassLoader extends ClassLoader{
 public MyClassLoader(ClassLoader parent) {
 super(parent);
 }
 public Class loadClass(String name) throws ClassNotFoundException {
 if(!"reflection.MyObject".equals(name))
 return super.loadClass(name);
 try {
 String url = "file:C:/data/projects/tutorials/web/WEB-INF/" +
 "classes/reflection/MyObject.class";
 URL myUrl = new URL(url);
 URLConnection connection = myUrl.openConnection();
 InputStream input = connection.getInputStream();
 ByteArrayOutputStream buffer = new ByteArrayOutputStream();
 int data = input.read();
 while(data != -1){
 buffer.write(data);
 data = input.read();
 }
 input.close();
 byte[] classData = buffer.toByteArray();
 return defineClass("reflection.MyObject",
 classData, 0, classData.length);
 } catch (MalformedURLException e) {
 e.printStackTrace();
 } catch (IOException e) {
 e.printStackTrace(); 
}
 return null;
 }
}


下面是一个使用MyClassLoader的例子。

public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException,
 InstantiationException {
 ClassLoader parentClassLoader = MyClassLoader.class.getClassLoader();
 MyClassLoader classLoader = new MyClassLoader(parentClassLoader);
 Class myObjectClass = classLoader.loadClass("reflection.MyObject");
 AnInterface2 object1 =
 (AnInterface2) myObjectClass.newInstance();
 MyObjectSuperClass object2 =
 (MyObjectSuperClass) myObjectClass.newInstance();
 //create new class loader so classes can be reloaded.
 classLoader = new MyClassLoader(parentClassLoader);
 myObjectClass = classLoader.loadClass("reflection.MyObject");

 object1 = (AnInterface2) myObjectClass.newInstance();
 object2 = (MyObjectSuperClass) myObjectClass.newInstance();
 
}

这里的reflection.MyObject加载使用的是类加载器,注意到它扩展了超类和实现了借口。这样做是为了这个例子的原因,在你自己的代码中,你将仅仅是实现扩展或是实现中的一种变可以了。

public class MyObject extends MyObjectSuperClass implements AnInterface2{
 //... body of class ... override superclass methods
 // or implement interface methods
}

实例解析

上面介绍的类容偏重于理论的讲解,下面来具体体验一下实战的代码解析。

请看下面的代码。


分享到:
评论

相关推荐

    java面试题--反射机制

    `Class`类在Java反射机制中扮演着核心角色,它是所有Java类的运行时表示。`Class`对象可以由以下几种方式获取: 1. **通过类的`Class`属性获取**:如`String.class`。 2. **通过对象的`getClass()`方法获取**:如`...

    JAVA反射机制应用

    在JAVA反射机制中,Class类和Field类、Method类、Constructor类是最重要的三个类,它们提供了访问类、字段、方法和构造函数的能力。 在获取某个对象的属性时,我们可以使用getField方法,例如: ```java public ...

    JAVA反射机制中的常见错误.txt

    当遇见java反射机制中的 “获取构造方法” 的错误时,一部分原因是忽略了最容易丢失的参数类型修改。

    java反射机制.zip

    java反射机制java反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制...

    Reflection_in_Java.zip_in_java 反射_java 反射机制_java反射_反射机制

    在Java反射机制中,`AccessibleObject`接口扮演着关键角色。它是`Constructor`、`Method`和`Field`的超接口,提供了`setAccessible(true)`方法,该方法可以绕过Java的访问权限检查,使私有成员可访问。但这应谨慎...

    java反射机制及Method.invoke解释

    在 Java 反射机制中,我们可以通过 Class 对象来获取类的信息,通过 Field 对象来获取类的成员变量,通过 Method 对象来获取类的方法。 例如,要获取某个对象的属性,我们可以使用以下代码: ```java public ...

    java反射机制 字符串——java对象

    在Java反射机制中,字符串可以用来表示类名、方法名或参数类型,是连接代码与运行时类信息的桥梁。 在Java中,将Java对象的数据封装成XML格式的字符串,通常涉及到对象序列化的过程。对象序列化是将对象的状态转换...

    java反射机制详解

    在 Java 反射机制中,Class 类是最重要的类,代表一个类。通过 Class 类,开发者可以获取类的信息,例如类的成员变量和方法。Field 类代表类的成员变量,Method 类代表类的方法,Constructor 类代表类的构造方法。...

    JAVA反射机制详解

    1. Class类:在Java反射机制中,Class类扮演了一个非常重要的角色。每个类都有一个与之对应的Class对象,通过这个Class对象可以获取类的详细信息。Class类的实例表示在JVM中的一个类或接口,它提供了方法来获取类的...

    java反射机制详解及Method.invoke解释.pdf

    在 Java 反射机制中,有三个主要的类:Class、Method、Field。Class 类表示 Java 中的类,Method 类表示 Java 中的方法,Field 类表示 Java 中的变量。这些类提供了许多方法来获取类、对象、方法、变量等信息。 ...

    Java反射机制 Java反射机制

    Java反射机制在JDK 1.1版本中就已经引入,但在JDK 1.5之后得到了进一步增强和完善,增加了泛型支持等功能,使得反射更加安全和强大。 #### 三、Java反射机制的核心概念与应用 1. **核心概念** - **Class对象**:...

    java反射机制源码

    java反射机制源码java反射机制源码java反射机制源码

    Java反射机制总结

    ### Java反射机制总结 #### 反射的概念与起源 反射的概念最早由Smith于1982年提出,指的是程序能够访问、检测并修改其自身状态或行为的能力。这一概念的提出迅速引起了计算机科学领域的广泛关注,并在之后的研究中...

    Java反射机制的实现_Reflection

    Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、对象等的内部信息。通过Java反射机制,开发者可以在不知道具体类名的情况下创建对象,调用方法,访问和修改私有成员变量,以及...

    候捷谈Java反射机制

    Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时获取和操作任何已知名称的类的内部信息。这一机制使得Java具备了一定的动态性,虽然在传统的分类中Java被视为静态类型语言。通过反射,开发者可以在...

    java 反射机制详解

    Java 反射机制是 Java 语言中的一个重要特性,它允许程序在运行时动态地获取类的信息(如类名、属性、方法等)并调用对象的方法,甚至修改对象的状态。这一机制极大地增强了 Java 程序的灵活性和可扩展性,尤其是在...

    反射实例-JAVA反射机制

    ### 反射实例—JAVA反射机制 #### 一、反射概念及原理 反射在计算机科学领域,特别是程序设计中,是指程序有能力访问、检测和修改其自身的结构和行为。这一概念最早由Smith于1982年提出,并迅速应用于各种编程语言...

    java反射机制和动态代理的原理

    java反射机制和动态代理的原理,熟悉反射机制和动态代理

    java 反射机制例子

    Java反射机制在实际开发中有着广泛的应用,例如: 1. **动态代理**:利用反射可以创建动态代理类,这对于实现AOP(面向切面编程)非常有用。 2. **框架开发**:许多Java框架,如Spring、Hibernate等,大量使用了反射...

Global site tag (gtag.js) - Google Analytics