反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力.
Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
在TIJ中,反射被作为一个子章节被放在RTTI(run time type information)中,书中的标题是Reflection:runtime class information,两者的区别就在于一个是type information一个是class information,RTTI相对与反射的局限就在与一个类的类型在编译期必须已知,编译器在编译器打开和检查.class文件,这样你就可以用"普通"的方式调用一个对象的所有方法,对于反射机制来说,.class文件在编译期是不可获取的,JVM在运行期获得一个未知类型对象,对它进行检查看它属于哪个特定的类,在这之后做任何其它事情之前,JVM必须加载这个类的class对象,因此,.class文件对JVM来说应该是可获取的(本地机器或网络取得)
关于动态代理:
动态代理机制的核心是InvocationHandler(调用处理器)这个接口。在动态代理中,是基于面向接口编程的。首先针对具体实例通过反射机制得到该类的类加载器、实现的接口,并对该类对象构造一个调用处理器类。并且实现invoke(Object proxy, Method method, Object[] args)方法,这个是核心处理方法。然后用构造实例的代理对象,这个代理对象的产生正是基于前面的实例的classloader、interfaces[](可能实现多个接口)及InvocationHandler实例。这样对代理对象调用实例的方法,就会将请求转发到调用处理器,在method.invoke(proxied, args);的前后的代码就是代理所需要实现的功能.
动态代理的内部实现——代码生成:
在Sun的Proxy实现中调用了 sun.misc.ProxyGenerator 类的 generateProxyClass( proxyName, interfaces) 方法,其返回值为 byte[] 和 class 文件的内存类型一致,即生成了一个代理类.
一个比较典型的动态代理程序:
使用Reflect会破坏封装?
从某种程度上说,确实是这样的,对于一个Class文件,你可以使用javap -private Classname命令获得所有的成员变量和方法(包括声明为private的),这样任何人都可以使用Method的invoke方法和Filed的set方法来调用private方法或设置private的成员变量.
调用某对象的某方法:
设置成员变量值:
值得注意的是:如果成员变量被声明为final,那么Field的set()方法不会改变该变量的值
Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
在TIJ中,反射被作为一个子章节被放在RTTI(run time type information)中,书中的标题是Reflection:runtime class information,两者的区别就在于一个是type information一个是class information,RTTI相对与反射的局限就在与一个类的类型在编译期必须已知,编译器在编译器打开和检查.class文件,这样你就可以用"普通"的方式调用一个对象的所有方法,对于反射机制来说,.class文件在编译期是不可获取的,JVM在运行期获得一个未知类型对象,对它进行检查看它属于哪个特定的类,在这之后做任何其它事情之前,JVM必须加载这个类的class对象,因此,.class文件对JVM来说应该是可获取的(本地机器或网络取得)
关于动态代理:
动态代理机制的核心是InvocationHandler(调用处理器)这个接口。在动态代理中,是基于面向接口编程的。首先针对具体实例通过反射机制得到该类的类加载器、实现的接口,并对该类对象构造一个调用处理器类。并且实现invoke(Object proxy, Method method, Object[] args)方法,这个是核心处理方法。然后用构造实例的代理对象,这个代理对象的产生正是基于前面的实例的classloader、interfaces[](可能实现多个接口)及InvocationHandler实例。这样对代理对象调用实例的方法,就会将请求转发到调用处理器,在method.invoke(proxied, args);的前后的代码就是代理所需要实现的功能.
动态代理的内部实现——代码生成:
在Sun的Proxy实现中调用了 sun.misc.ProxyGenerator 类的 generateProxyClass( proxyName, interfaces) 方法,其返回值为 byte[] 和 class 文件的内存类型一致,即生成了一个代理类.
一个比较典型的动态代理程序:
package com.juice.rtti.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; interface TestInterface { void doSth(); } class RealSub implements TestInterface{ @Override public void doSth() { System.out.println("dosth"); } } class Handler implements InvocationHandler{ private TestInterface real; public Handler(TestInterface real) { this.real = real; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("hello"); return method.invoke(real, args); } } public class ProxyTest { public static void main(String[] args) { TestInterface real = new RealSub(); TestInterface proxy = (TestInterface)Proxy.newProxyInstance (TestInterface.class.getClassLoader(), new Class<?> [] {TestInterface.class}, new Handler(real)); proxy.doSth(); } }
使用Reflect会破坏封装?
从某种程度上说,确实是这样的,对于一个Class文件,你可以使用javap -private Classname命令获得所有的成员变量和方法(包括声明为private的),这样任何人都可以使用Method的invoke方法和Filed的set方法来调用private方法或设置private的成员变量.
调用某对象的某方法:
static void callHiddenMethod(Object a, String methodName) throws Exception { Method g = a.getClass().getDeclaredMethod(methodName); g.setAccessible(true); g.invoke(a); }
设置成员变量值:
WithPrivateFinalField pf = new WithPrivateFinalField(); System.out.println(pf); Field f = pf.getClass().getDeclaredField("i"); f.setAccessible(true); System.out.println("f.getInt(pf): " + f.getInt(pf)); f.setInt(pf, 47);
值得注意的是:如果成员变量被声明为final,那么Field的set()方法不会改变该变量的值
发表评论
-
UseCase驱动的过程
2008-10-26 15:26 0本章讨论理解问题和建立问题模型的方法,RUP推荐的方法就是Us ... -
以架构为中心的过程
2008-10-23 09:40 0模型的重要性 RUP有很大 ... -
动态结构:迭代开发
2008-10-22 09:15 0为什么要迭代: 两个常阻碍软件项目成功的错误假设: 错误假设 ... -
RUP导论:动态结构:迭代开发
2008-10-04 20:46 0本章描述RUP的生命周期结构,即整个开发过程是如何进行的. 迭 ... -
RUP导论:最佳软件开发实践
2008-10-03 22:51 0本章讨论最佳软件开发实践,并对RUP做了大体介绍. 软件 ... -
Array
2008-09-28 00:37 0数字与容器类的不同之处: 效率,类型,和装载原生数据类型的能力 ... -
Thinking in Java 笔记:RTTI
2008-09-21 21:09 1817RTTI即run-time type identifica ... -
Generics
2008-09-21 21:05 0泛型是Java SE 1.5的新特性,泛型的本质是参数化类 ... -
Thinking in Java 笔记:Inner Class
2008-09-15 14:08 1088将一个类的定义放在另一个类的定义内部,这就是内部类 当你生成 ... -
String
2008-09-12 10:55 0String 类被声明为final 所以它不能被继承 一个St ... -
Thinking in Java 笔记: Initialication & Cleanup
2008-09-05 14:42 1067成员变量和局部变量初始化: 成员变量若不显式初始化j ... -
Thinking in Java 笔记:Operators
2008-09-05 14:42 1408数学没学好,补充点数学 ... -
Thinking in Java 笔记:Everything is an Object
2008-09-05 14:41 1468无聊了,当当买了本原版的 Thinking in java 4 ...
相关推荐
Thinking in C: Foundations for Java & C++ by Chuck Allison produced by Bruce Eckel Chapter 1: Introduction and Getting Started40 MinutesStart Lecture Chapter 2: Fundamental Data Types41 ...
根据提供的文件信息,以下是对文件《Thinking in Java 4th Edition Annotated Solutions Guide》中所包含知识点的详细解释: 首先,文件标题《Thinking in Java 4th Edition Annotated Solutions Guide》指出了这是...
### Thinking in Java 读书笔记知识点总结 #### 一、万事万物皆对象 1. **对象存储位置** - **寄存器**:程序无法直接控制。 - **栈(Stack)**:存储基本类型数据和对象引用,但对象本身不在此处。 - **堆(Heap)...
### Thinking in Java 自学笔记——第二章 一切皆对象 #### 重要概念解析 ##### 2.1 用引用操纵对象 在Java中,一切都被视为对象,这意味着无论是字符串、数字还是其他数据类型都可以被视为对象来进行操作。当...
《Thinking in Java》第四版由布鲁斯·埃克尔(Bruce Eckel)撰写,他是MindView公司的总裁。这本书被广泛认为是学习Java编程语言的经典教材之一。从读者的反馈来看,《Thinking in Java》不仅覆盖了Java的核心概念...
读书笔记:Thinking in Java (Java 编程思想)
《Thinking in Java》是一本深度解析Java编程语言的经典著作,其深入浅出的讲解和丰富的实例使得读者能够全面理解Java的精髓。以下是对书中部分关键知识点的总结: 1. **Java 泛型**:泛型是Java SE 5.0引入的重要...
研讨课 Hands-on Java研讨课CD Thinking in Objects研讨课 Thinking in Enterprise Java Thinking in Patterns(with Java) Thinking in Patterns研讨课 设计咨询与复审 附录B 资源 软件 编辑器与IDE 书籍 分析与设计...
《Thinking in Java》是Bruce Eckel的经典之作,第四版(TIJ4)更是Java程序员必读的书籍之一。这本书深入浅出地介绍了Java语言的核心概念和技术,包括面向对象编程、集合框架、多线程、网络编程等众多主题。源码是...
Thinking in Java 自学笔记——第一章 对象导论 本章节总结了面向对象程序设计(Object-oriented Programming, OOP)的基本概念和原则,以帮助读者更好地理解 Java 编程语言。以下是对标题、描述、标签和部分内容的...
《Thinking in Java》是Bruce Eckel的经典之作,它深入浅出地介绍了Java语言的核心概念和技术。这本书的练习题是学习Java的重要组成部分,因为它们能够帮助读者巩固理论知识并提升实践能力。以下是对"Thinking in ...
《Thinking in Java》是Bruce Eckel的经典之作,第四版涵盖了Java编程语言的广泛主题,适合初学者和有经验的程序员。这本书深入浅出地讲解了Java的核心概念和技术,旨在帮助读者建立坚实的编程基础,并理解面向对象...
《王者归来之Thinking in Java读书笔记》是对Bruce Eckel的经典之作《Thinking in Java》第四版的深度学习与总结。这本书是Java程序员的必备参考书,它深入浅出地阐述了Java语言的核心概念和技术,旨在帮助读者理解...
《Thinking in Java》是Bruce Eckel的经典之作,被誉为学习Java编程的权威指南。该书以其深入浅出的方式,详尽地介绍了Java语言的核心概念和技术。第三版是此书的一个重要里程碑,它涵盖了Java语言的诸多关键特性,...
《Thinking in Java》是一本备受推崇的Java编程教材,由Bruce Eckel撰写,被誉为Java学习者的必读之作。这本书深入浅出地介绍了Java语言的核心概念和技术,覆盖了从基础到高级的主题,对于有一定Java基础的读者来说...
《Thinking in Java》是Bruce Eckel的经典之作,第四版更是被广大Java开发者视为学习和进阶的重要参考书籍。这本书深入浅出地介绍了Java语言的核心概念和技术,包括面向对象编程、集合框架、多线程、网络编程、GUI...
《Thinking in Java》是Bruce Eckel的经典编程教材,它深入浅出地介绍了Java语言的核心概念和技术。这本书以其详尽的解释、丰富的示例和实践性强的习题深受程序员喜爱。"Thinking in Java 习题答案"是配套的解答集,...
《Thinking in Java》是 Bruce Eckel 编著的一本经典的Java编程教材,它深受程序员喜爱,被誉为学习Java的必备参考书。这本书全面深入地探讨了Java语言的核心概念和技术,不仅适合初学者,也对有经验的程序员提供了...
《Thinking in Java》第二版是Bruce Eckel所著的一本权威性的Java编程教程,由MindView, Inc.出版。这本书受到了读者的高度评价,被认为是比其他Java书籍更出色的学习资源,其深度、完整性和精确性都是同类书籍中的...