一.Annotation,java.lang.annotation.ElementType枚举
ElementType表示程序元素的类型,和@Target元注释类型一起使用,以指定在什么情况下使用注释类型合法的.
1)CONSTRUCTOR:构造方法声明
2)FIELD:字段声明
3)LOCAL_VARIABLE:局部变量声明
4)METHOD:方法声明
5)PACKAGE:包声明
6)PARAMETER:参数声明
7)TYPE:类/接口(包括注释)或者枚举声明.
8)ANNOTATION_TYPE:注释类型声明
二.RetentionPolicy枚举:
注释保留策略,他们与@Retention元注释类型一起使用,以指定保留注释的场景.
1)CLASS:编译器将把注释记录在类文件中,但在运行时VM不需要保留注释.
2)RUNTIME:编译器将把注释记录在类文件中,在运行时可以被VM保留,并可以被反射机制所获取.
3)SOURCE:注释只保留在原文件中.
@Documented:指定某一类型的注释将通过javadoc工具进行文档化.将成为API文档的一部分.
@Inherited:指定此注释类型可以被自动继承.如果注释类型声明中存在Inherited元注释,那么此元素将会自动继承父类/接口的注释类型.
@Retention:指定注释类型的注释保留策略,默认为RetentionPolicy.CLASS.
@Target:指示注释类型所适用的元素种类.如果注释类型声明中不存在Target元注释,则此注释可以被声明在任意元素类型上.Target允许指定多个ElementType作为其value.它和
ElementType枚举配合使用.
三.AnnotatedElement接口:
表示目前正在VM中运行的程序的一个已注释元素.该接口允许反射性的读取注释.
其中实现类有AccessibleObject(AccessibleObject子类有Constructor,Field,Method),Class和Package
方法列表:
1)public boolean isAnnotationPresent(Class<? extends Annotation> annotation):
如果指定的注释存在于此元素上,则返回true.
2)public Annotation[] getAnnotations():
返回此元素上存在的所有注释.如果没有注释,则返回长度为0的数组.
3)public Annotation getDeclaredAnnotation():
返回直接存在于此元素上的所有注释。与此接口中的其他方法不同,该方法将忽略继承的注释。
(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)
该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。
四.Member接口:
成员是一种接口,反映有关单个成员(字段或方法)或者构造方法的标识信息.
其实现类有Constructor,Field,Method.
1) public Class<?> getDeclaringClass():
返回表示声明此Member表示的成员的Class对象,即此成员所属的原声明类对象.
2) public String getName():
返回此成员或者构造方法的简单命名.
3) public int getModifiers():
返回整数,表示此Member的修饰符信息.可以通过Modifier类的辅助方法来检测.
4) public boolean isSynthetic():
如果此成员是编译器引入的,则返回 true.
五.几种特殊的类型(Type接口的子接口)
GenericArrayType:泛型化数组类型.例如: <T> T[];
ParameterizedType:参数化类型.例如Collection<String>..方法列表:
WildcardType:表示一个通配符类型表达式,例如:?,? extends Number
六.AccessibleObject类
AccessibleObject类是Field,Method和Constructor对象的基类,它提供了将反射的对象标记为在使用时取消默认java语言访问控制检测的能力.对于公共成员/默认访问成员
/受保护成员和私有成员,在分别使用Filed/Method/Constructor对象来设置或者获取字段值/调用方法以获取执行结果时/创建或初始化类的新实例时,均会执行访问检测.
此类实现了AnnotatedElement接口.
1)public void setAccessible(boolean flag) throws SecurityException:
将对象的accessible标记设置为指定的值.如果值为true,则指示反射的对象在使用时应取消java语言的访问检测.
例如:private Date date;
此属性为private,如果在类的外部,是不能直接访问其值的.但是通过如下方式却可以.
DateTest test = new DateTest();
Field[] fields = test.getDeclareFields();
try{
for(Field f: fields){
f.setAccessible(true);
Date d = (Date)f.get(test);
System.out.print(d.toString());
}
}
七.Array类:
Array类提供了动态创建和访问java数据的能力.
1) static Object get(Object array,int index):
获取指定数组的相应索引的值.
2) static void set(Object array,int index,Object value):
设置数组的值.
3) static Object newInstance(Class<?> type,int length):
创建一个指定长度和数据类型的数组.
八.Constructor类:
Constructor提供了类的单个构造方法的信息以及对它的访问权限.
1) public T newInstance(Object...args):
使用此Constructor对象表示的构造方法来创建该构造方法声明类的实例.个别参数会自动解包,以匹配基本形参,必要时,基本参数和引用参数都要进行方法调用转换.如果构造器的参数列表为0,可以传递null或者空数组.
如果所需的访问检查和参数检查获得成功并且实例化继续进行,这是构造方法的声明类尚未初始化,则初始化此类.
会执行访问权限校验.如果setAccessible(true),那么在反射机制下,私有构造函数也可以创建实例.(打破单例设计的一个潜在可能)
九.Filed类:
提供了对类的成员属性进行操作的能力,以及对它的动态访问权限.反射的字段可能是一个类的静态字段或者实例字段.
1) public boolean isEnumConstant():
如果此字段表示枚举类型的元素,则返回true.
2) public Type getType():
返回一个Type对象,表示此Field对象所表示字段的声明类型.
3) public Object get(Object obj):
返回指定对象上此Field的值.如果该值为基本类型,将会被包装成类.
如果此属性为static,则忽略obj变量,即使obj为null.
此方法将会被安全访问权限检测.
4) public void set(Object obj,Object value) throws ..:
对obj对象上此属性进行赋值.
如果此属性为静态,则忽略obj值,即使obj为null.
此方法执行会被访问权限检测.
如果此属性为final,则抛出异常.
十.Method类:
此类提供了反射下访问类方法以及执行方法的能力,方法可以是static的.
1) public Class<?> getReturnType():
获取此方法的返回值类型.
2) public Type getGenericReturnType():
获取此方法的正式返回类型的type对象,Type可能是参数化type等.(泛型化返回结果)
3) public Class<?>[] getParameterTypes():
获得此方法的参数列表数组,如果无参,将返回尺寸为0的空数组.
4) public Object invoke(Object obj,Object...args) throws ...:
调用指定对象的此方法,并获得结果,此方法将会检测访问权限.(setAccessible(true)).如果底层方法是静态的,此时如果类没有实例化,则执行类初始化.如果方法是void类型,则返回null.
Class类可以获得所有对Constructor,Filed,Method列表的方法.这是类反射的引导类.
十一.Modifier类
Modifier类是一个辅助类,大量的静态方法,可以通过检测Member.getModifier()的值来获得成员的修饰符信息.
例如:Modifier.isAbstract(int)来检测成员是否为被abstract修饰.
十二.动态代理
InvocationHandler接口:代理实例的调用处理程序,每个代理实例(Proxy instance)都需要一个invocationHandler来执行调用时的代理过程.
此接口只有一个方法:
- Object invoke(Object proxy,Method method,Object[] args) throws....
在代理实例上处理方法调用并返回结果;proxy参数为代理实例,Method为执行的方法,args为方法需要的参数列表.
Proxy类:动态代理:
静态代理即为代理类和实际类需要具有相同的接口列表,如果一个类需要有多种代理方式,就需要创建多个代理类,形成子类的数量巨多.动态代理类就避免了此问题,它允许在运行时指定需要代理的接口列表,动态创建代理实例.
可以通过如下方式获取代理实例:
Foo f = (Foo)Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[]{Foo.class},new FooInvocationHandler());
代理类(Proxy代理所创建的子类)具有如下属性:
1) 代理类为公共的/最终的/而不是抽象的.即不可被继承性.
2) 代理类扩展java.lang.reflect.Proxy.
3) 代理类会按同一顺序准确的实现其创建时指定的接口.
4) 对代理类class实例进行getInterfaces将返回一个包含相同接口列表的数组(按其创建时指定的顺序).
5) 可以通过Proxy.isProxyClass(Class proxy)来检测一个实例的类是否为代理类,通过Proxy.newInstance创建的类都是代理类.
6) 代理类是由底层字节码重构技术创建而来.代理类是一种特殊的存在于运行时的类.
代理实例proxy与实际类的类型匹配关系:
- proxy instanceOf Foo将返回true.
- (Foo)proxy强制类型转换成功.
对于代理类调用方法,将会指派到invocationHandler.invoke()方法上.
代理实例上的java.lang.Object中声明的hashCode,equals,toString方法的调用将按照与编码和指派接口方法调用相同的方式进行编码,也将指派到invocationHandler.invoke上.即使是Object的方法调用,也会分配给handler执行.
////////////////////////////////////////////////ProxyDemo:
public class ProxyTestMain { /** * @param args */ public static void main(String[] args) { DateOper oper = new DateOperImpl(); DateOper proxyInstance = (DateOper)Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{DateOper.class}, new Invocation(oper)); proxyInstance.setDate(new Date()); System.out.println(proxyInstance.getDate().getTime()); System.out.println(proxyInstance.toString()); } interface DateOper{ public void setDate(Date date); public Date getDate(); } static class DateOperImpl implements DateOper{ private Date date; @Override public void setDate(Date date) { this.date = date; System.out.println("SetDate invoked!"); } @Override public Date getDate() { System.out.println("GetDate invoked!"); return date; } public String toString(){ System.out.println("ToString invoked!"); return super.toString(); } public int hashCode(){ System.out.println("HashCode invoked!"); return super.hashCode(); } } static class Invocation implements InvocationHandler{ private Object obj;//被代理实例 public Invocation(Object obj){ this.obj = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("proxy:" + proxy.getClass() + "//" + Proxy.isProxyClass(proxy.getClass())); System.out.println("method:" + method.getName()); return method.invoke(obj, args); } } }
相关推荐
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、字段以及方法等对象。这一机制的核心在于`java.lang.Class`类和相关的API,它们提供了对类元数据的访问,使得我们能够在运行时...
10. **反射和动态代理**:`java.lang.reflect`包提供了反射API,允许程序在运行时检查和操作类、接口、字段和方法。动态代理机制则允许在运行时创建实现一组指定接口的新类。 通过`jdk-6u10-api-en`这个压缩包,你...
22. **java.lang.reflect**:反射机制的类和接口,用于获取类和对象的信息。 23. **java.math**:提供大整数(BigInteger)和高精度小数(BigDecimal)计算的类。 24. **java.net**:网络编程的类,包括Socket、...
8. **反射机制**:探讨Java反射API的使用,包括动态获取类信息、创建对象、调用方法等功能,这对于理解和调试程序有很大的帮助。 9. **JVM内部机制**:简述Java虚拟机的工作原理,包括类加载、内存管理、垃圾回收...
7. **反射机制**:Java反射机制允许在运行时动态访问类的信息,如创建对象、调用方法、修改字段等。这在插件系统、元编程和单元测试等领域非常有用。 8. **JVM内存管理**:了解堆内存、栈内存、方法区以及垃圾回收...
8. **反射机制**:讨论Java的反射机制,如何在运行时动态获取类的信息并调用方法。 9. **Java Swing与JavaFX**:介绍用于创建桌面应用的图形用户界面(GUI)工具包,如Swing组件和JavaFX框架。 10. **Java Applet*...
8. **Java标准库API**:这部分可能会简述Java的主要包,如java.util、java.io、java.net和java.awt,以及它们包含的重要类和接口。 9. **Java高级特性**:最后,思维导图可能涉及Java的最新特性,如lambda表达式、...
7. **反射机制**:介绍Java反射API,用于在运行时检查类、接口、字段和方法的信息,以及动态创建对象和调用方法。 8. **JNI与JVM**:简述Java本地接口(JNI)的使用,允许Java代码调用C/C++函数,以及对Java虚拟机...
12. **反射与注解**:讲解Java反射机制,如何动态访问和修改类、接口、方法,以及注解的使用和自定义注解的创建。 13. **Java高级特性**:如模块化系统(Project Jigsaw)、Optional类、并发工具类(如...
8. **反射机制**:解释Java的反射API,如何在运行时动态获取类的信息,以及动态创建和调用对象的方法。 9. **泛型**:介绍泛型的使用,如何提高代码的类型安全性和重用性,以及通配符的运用。 10. **JVM原理**:...
12. **Java API**:讲解常用的Java类库,如Math、Date、Calendar、Collections等。 13. **设计模式**:介绍常见的设计模式,如工厂模式、单例模式、观察者模式等,提升代码的可读性和可维护性。 14. **Java Swing...
14. **反射机制**:解释Java反射API的使用,如何在运行时动态获取类的信息和调用方法。 15. **Java标准库**:简述Java API中一些常用的类库,如IO、集合、网络编程和日期时间API等。 通过学习这份北大Java讲义,...
10. **JVM与内存管理**:简述Java虚拟机的工作原理,包括垃圾回收机制和内存区域,这对优化程序性能至关重要。 在学习过程中,读者需要通过编写代码实践来加深理解,逐步提升编程技能。同时,书中可能还提供了各种...
8. **反射机制**:介绍Java反射API,用于在运行时检查类、接口、字段和方法的信息,以及动态创建对象。 9. **JVM内部机制**:简述Java虚拟机的工作原理,包括类加载、内存管理和垃圾回收。 10. **Java SE和Java EE...
六、Java反射与注解 16. 反射:掌握Class类的使用,动态获取类信息,创建对象,调用方法和访问字段。 17. 注解:了解注解的元数据功能,以及自定义注解和使用反射处理注解。 七、Java虚拟机(JVM) 18. 内存管理:...
6. **Java EE**:简述Java企业版技术,如Servlet、JSP和EJB。 7. **Java并发编程**:深入讨论并发API,如ExecutorService、Future、Callable和并发集合。 8. **Java 8新特性**:介绍Lambda表达式、Stream API和...
10. **Java标准库和API**:书中会介绍Java SE标准库中的重要类和接口,如Math类、Date/Time API、反射机制,以及如何通过API文档查找和使用类库。 通过阅读和实践《Java程序设计技巧与开发实例》中的内容,读者不仅...
4. **反射与动态代理**:Java的反射机制允许程序在运行时检查和操作类、接口、方法和字段。动态代理则允许创建代理类以实现运行时的拦截和增强。这两部分内容对于框架设计和元编程非常重要。 5. **枚举与注解**:...
9. **反射与注解**:讨论Java反射机制,允许在运行时检查类、接口、字段和方法的信息,以及注解的使用,用于元数据注解和编译时或运行时的处理。 10. **JVM与内存管理**:简述Java虚拟机的工作原理,包括类加载机制...
5. **Java反射与注解**:介绍反射API,允许在运行时检查和修改类,以及注解的使用和自定义。 6. **模块系统**:讲解Java 9引入的模块系统,如何组织和打包应用程序,提高可维护性和可升级性。 7. **数据库编程**:...