- 浏览: 140137 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
chxiaowu:
不错。1111111111
Java静动态代理模式示例 -
kufish001:
引用 当执行 java ***.class 的时候, j ...
深入探讨Java的类加载机制 -
centgo:
Vector 是线程安全的,ArrayList速度>Ve ...
ArrayList,Vector, LinkedList 的存储性能和特性 -
sonsyboy:
JVM的工作原理,谢谢博主!
解析JAVA中的内存分配 -
zhaoxudonglove:
现在越来越觉得java基础很重要而且还很有趣了!谢谢博主的解析 ...
解析JAVA中的内存分配
摘要
开发者通过各种各样的方法来尝试避免单调冗余的编程。一些编程的规则例如继承、多态或者设计模型可以帮助开发者避免产生多余的代码。不过由于软件开发方面存在着不确定性,因此这些规则并不能消除代码维护和重新编写的需要。在很多时候维护都是不可避免的,只有不能运作的软件才是从不需要维护的。不过,这篇文章介绍了你可以使用Java的Reflection API的功能来减少单调的代码编写,并可以使用活动的代码产生来克服reflection的限制。
数据配置(由外部的源头得到数据并且将它装载到一个Java对象中)可以利用reflection的好处来创建一个可重用的方案。问题是很简单的:将数据由一个文件装入到一个对象的字段中。现在假设用作数据的目标Java类每星期改变一次?有一个很直接的解决方法,不过你必须不断地维护载入的过程来反映任何的改变。在更复杂的环境下,同样的问题可能会令系统崩溃掉。对于一个处理过运用XML的大型系统的人来说,他就会遇到过这个问题。要编写一个载入的过程通常是非常单调乏味的,由于数据源或者目标Java类的改变,你需要经常更新和重新编写代码。在这里我要介绍另一个解决方案,那就是使用映射,它通常使用更少的编码,并且可以在目标Java类发生改变后更新自己。
最初,我想介绍一个使用Reflection在运行期间配置数据的方案。在开始的时候,一个动态、基于映射的程序要比一个简单的方法更有吸引力多了。随后,我要揭示出运行时Reflection的复杂性和冒险性。这篇文章将介绍由运行时的Reflection到活动的代码产生。
由简单到复杂
我的第一个方案使用一个载入类将数据从一个文件载入到对象中。我的源代码含有对StringTokenizer对象下一节点方法的多次调用。在修改多次后,我的编码逻辑变得非常的直接、系统化。该类构造了专用的代码。在这个初始方案中,我只需要使用3个基本的对象:
1、Strings
2、Objects
3、Arrays of objects
你可以影射类的对象来产生代码块,如下表所示:
被影射来产生代码块的对象
我已经使用这个方案作了几次编码,因此我在写代码之前我已经知道该方案和代码的结构。难点在于该类是变化的。类的名字、成份和结构在任何时候都可能发生变化,而任何的改变你都要重新编写代码。虽然会发生这些变化,但是结构和下载的流程仍然是一样的;在写代码前,我仍然知道代码的结构和成份。我需要一个方法,来将头脑中的编码流程转换为一个可重用的、自动的形式。由于我是一个有效率的编程者,我很快就厌倦了编写几乎一样的代码,这时我想到了映射。
数据配置通常需要一个源到目的数据的影射。影射可以是一个图解、DTD(document type definition,文档类型定义),文件格式等。在这个例子中,映射将一个对象的类定义解释为我们要映射的流程。映射可以在运行时复制代码的功能。在需要重写代码时,我将载入的过程用映射来代替,它所需要的时间和重写是一样的。
载入的工程可以概括为以下几步:
1、解释:一个影射决定你在构造一个对象时需要些什么
2、请求数据:要满足构造的需要,要进行一个调用来得到数据
3、拖:数据由源中得到。
4、推:数据被填充入一个对象的新实例
5、如果必要的话,重复步骤1
你需要以下的类来满足以上的步骤:
.数据类(Data classes):由ASCII文件中的数据实例化。类定义提供数据的影射。数据类必须满足以下的条件:
.它们必须包含有一个构造器来接收全部必需的参数,以使用一个有效的状态来构造对象;
.它们必须由对象构成,这些对象是reflective过程知道如何处理的
.对象装载器(Object loader):使用reflection和数据类作为一个影射来载入数据。产生数据请求。
.载入管理器(Load manager):作为对象装载器和数据源的中介层,将对数据的请求转换为一个数据指定的调用。这可以令对象载入器做到与数据源无关。通过它的接口和一个可载入的类对象通信。
.数据循环接口(Data iterator interface):载入管理器和载入类对象使用这个接口来由数据源中得到数据。
一旦你创建了支持的类,你就可以使用以下的声明来创建和影射一个对象:
FooFileIterator iter = new FooFileIterator(fileLocation, log);
LoadManager manager = new FooFileLoadManager(iter);
SubFooObject obj =
(SubFooObject)ReflectiveObjectLoader.initializeInstance(SubFooObject.class, manager,log);
通过这个处理,你就创建了一个包含有文件内容的SubFooObject实例。
局限
开发者必须决定使用哪个方案来解决问题是最好的;通常做出这个决定是最困难的部分。在考虑使用reflection作数据配置时,你要考虑到以下一些限制:
1、不要令一个简单的问题复杂化。reflection是比较复杂的,因此在必要的时候才使用它。一旦开发者明白了reflection的能力,他就想使用它来解决所有的问题。如果你有更快、更简单的方案来解决问题时,你就不应该使用reflection(即使这个更好的方案可能使用更多的代码)。reflection是强大的,但也有一些风险。
2、考虑性能。reflection对性能的影响比较大,因为要在运行时发现和管理类属性需要时间和内存。
重新评估方案
如上所述,使用运行时reflection的第一个限制是“不要令简单的问题复杂化”。在使用reflection时,这是不可避免的。将reflection和递归结合起来是一个令人头痛的问题;重新看代码也是一件可怕的事情;而准确决定代码的功能也是非常复杂的。要知道代码的准确作用的唯一方法是使用一些取样数据,逐行地看,就象运行时一样。不过,对于每个可能的数据组合都使用这种方式几乎是不可能的。在这种情况下,使用单元测试代码可能有些帮助,不过也很可能出现错误。幸运的是,还有一个可选的方法。
可选的方法
由上面列出的限制可以看到,在某些情况下,使用reflective载入过程可能是得不偿失的。代码产生提供了一个通用的选择方法。你也可以使用reflection来检查一个类并且为载入过程产生代码。
Andrew Hunt和David Thomas介绍了两类的代码产生器,见The Pragmatic Programmer(http://www.javaworld.com/javaworld/jw-11-2001/jw-1102-codegen-p2.html#resources)
1、Passive(被动):被动的代码产生器在实现代码时需要人工的干预。许多的IDE(集成开发环境)都提供相应的向导来实现。
2、Active(主动):主动的代码产生指的是代码一旦创建,就不再需要修改了。如果有问题产生,这个问题也应该在代码产生器中解决,而不是在产生的源文件中解决。在理想的情况下,这个过程应该包含在编译的处理过程中,从而确保类不会过期。
代码产生的优点和缺点包含有以下方面:
优点:
.简单:产生的代码通常是更便于开发者阅读和调试。
.编译过程的错误:Reflexive在运行时出现错误的机会要比编译的期间多。例如,改变被载入的对象将有可能令产生的载入类抛出一个编译的错误,不过reflexive过程将不会看到任何的区别,直到在运行时遇到这个类。
缺点:
.维护:使用被动的代码产生,修改被载入的对象将需要更新或者重新产生载入的类。如果该类被重新产生,那么自定义的东西就会丢失。
回头再来看看主动代码产生的好处
在这里我们可以看到在运行时使用reflection是不可以接受的。主动的代码产生有着reflection的全部好处,但是没有它的限制。还可以继续使用reflection,不过只是在代码的产生过程,而不是运行的过程。理由如下:
1、更少冒险:运行时的reflection明显是更冒险的,特别是问题变得复杂的时候。
2、基于单元测试,但并不是编译器
3、多功能性:产生的代码有着runtime reflection的全部好处,而且有着runtime reflection没有的好处。
4、更易懂:虽然经过多次的处理,但是将递归和reflection结合仍然是很复杂的。产生源代码的方式更加容易解释和理解。代码产生过程需要递归和reflection,但得到的结果是可查看的源代码,而不是难以理解的东西。
写代码产生器
要写一个代码产生器,在思考的时候,你不能只是简单地编写一个方案来解决一个问题,你应该看得更远。代码产生器(以及reflection)需要你作更多的思考。如果你只是使用runtime reflection,你就不得不在运行时概念化问题,而不是使用简单、兼容性好的源代码来解决问题。代码产生要求你从两个方面来查看问题。代码产生过程会将抽象的概念转变为实际的源代码。Runtime reflection则一直是抽象的。
代码产生过程将你的思考过程转变为代码,然后产生并且编译代码。编译器会让你知道你的思考过程在语法上是否正确;单元测试则可以验证代码在运行时的行为。就动态特性方面,runtime reflection就不能达到这个级别的安全性。
代码产生器
在经历后几次失败的设计后,我认为最简单的方法是:在载入过程中,为每一种需要实例化的类产生一个方法。一个方法工厂产生每个特别类的正确方法。一个代码编译对象缓冲来自代码工厂的方法请求,以产生最终源代码文件的内容。
MethodCode对象是代码产生过程的核心。以下就是一个int的代码产生对象的例子:
public class MethodForInt extends MethodCode {
private final static MethodParameter param = new MethodParameter(SimpleFileIterator.class, "parser");
public MethodForInt(Class type, CodeBuilder builder){
super(type, builder);
}
public MethodParameter[] getInputParameters(){
return new MethodParameter[]{
param
};
}
}
发表评论
-
Java静动态代理模式示例
2011-11-16 13:03 1467设计模式 1.静态代理模式 使用场合: 为其他对象提供一种 ... -
Java 连接池
2008-12-07 19:01 754package jo.service.webservice; ... -
深入探讨Java的类加载机制
2008-12-07 18:57 2218Java 语言是一种具有动态性的解释型编程语言,当指定程序 ... -
解析JAVA中的内存分配
2008-12-07 18:55 2021照编译原理的观点 ... -
BASE64编码规则
2008-12-07 18:18 55281、编码规则: Base64编 ... -
Servlet读取Cookie
2008-12-07 18:17 5437Cookie概述 Cookie是服务器发送给浏览器的体 ... -
Java同步机制:sychronized对代码影响
2008-12-07 18:12 1355Java对多线程的支持与同步机制深受大家的喜爱,似乎看起来使用 ... -
hibernate二级缓存攻略
2008-06-21 17:05 1131文章来源:http://www.iteye.com/topic ... -
实战DDD(Domain-Driven Design领域驱动设计)
2008-06-17 17:47 1515http://www.jdon.com/mda/ddd.htm ... -
容器和bean的基本原理
2008-01-23 14:46 1253org.springframework.beans及org.s ... -
注入依赖
2008-01-23 14:45 1024依赖注入(DI)背后的基本原理是对象之间的依赖关系(即一起工作 ... -
提高JSP的性能
2008-01-23 14:39 876方法一:在servlet的init() ... -
JSTL
2008-01-23 14:35 1583JavaServer Pages Standard Tag L ... -
EL 表达式
2008-01-23 14:34 4714JSP2.0之后,EL已经正式纳入成为标准规范之一。 JSF ... -
挖掘Jakarta Commons中隐藏的宝贝(二)
2008-01-23 14:32 10812.Commons Collections中的算子 算子成为C ... -
挖掘Jakarta Commons中隐藏的宝贝(一)
2008-01-23 14:31 1083如果你不熟悉Jakarta Commons话,那么很有可能你已 ... -
海量数据库的查询优化及分页算法方案
2008-01-23 14:20 930随着“金盾工程”建设 ... -
ServletContext接口
2007-12-10 18:24 1515对于web容器来说,ServletContext接口定义了一个 ... -
java学习的四个阶段(二)
2007-12-01 20:15 1149第三阶段: 您将学习 J2EE 技术 ... -
java学习的四个阶段(一)
2007-12-01 20:13 1044第一阶段: 您将学习 JAVA 编程的基础部分,即 J2SE ...
相关推荐
Java 8 Nashorn脚本引擎是Java平台上的一个强大工具,它允许开发者在Java应用程序中直接执行JavaScript代码,极大地增强了Java与动态语言的交互能力。Nashorn引擎首次引入于Java 8,作为对之前Rhino JavaScript引擎...
1. 类和对象:Java是面向对象的语言,源代码会展示如何定义类,创建对象,以及如何利用继承、封装和多态等面向对象原则来设计软件。 2. 异常处理:Java中的异常处理机制是通过try-catch-finally语句块实现的,源...
《JAVA_API_1.8_中文手册》是一个针对Java ...通过深入学习和理解这些API,你将能够更有效地利用Java 1.8的特性,编写出高效、优雅的代码。这份手册的CHM格式使得内容便于搜索和查阅,是每一位Java开发者必备的参考书。
【JAVA游戏API】是开发者基于Java编程语言...开发者通过集成LWJGL来处理图形,利用AIO进行高效的网络通信,同时利用反射来提高插件系统的灵活性,这些技术的结合为创建一个基础的Java网络游戏骨架奠定了坚实的基础。
综上所述,"High performance Java reflection.zip"可能包含有关如何利用ReflectASM提高Java反射性能的详细信息,这对于优化性能敏感的Java应用程序来说是非常有价值的。学习和掌握这些知识可以帮助开发者更好地平衡...
在本教程中,我们将深入探讨Java Reflection API的基本概念、使用场景以及如何有效地利用它来增强你的Java应用。 1. **基础知识** - **类的加载与初始化**:反射API首先涉及到类的加载过程。Java虚拟机(JVM)在运行...
7. **Annotations(注解)**:提供了一种元数据机制,用于在代码中添加元信息,用于编译时检查、运行时处理或自动生成代码。 8. **NIO.2(非阻塞I/O)**:虽然正式引入是在Java 7,但Java 1.5开始引入了部分非阻塞I...
Java API文档中文版是Java开发人员的重要参考资料,它详尽地介绍了Java平台标准版(Java SE)中的类库、接口和方法。这份文档是开发者学习和理解Java编程语言的关键工具,帮助他们有效地利用Java提供的各种功能。...
Java代码动态生成是一种在运行时根据特定需求创建和执行代码的技术。这在处理复杂逻辑、元编程、插件系统或优化性能...理解每种方法的工作原理和限制,可以帮助我们更好地利用Java的动态特性,提高代码的灵活性和效率。
这篇博文“利用java反射、注解及泛型模拟ORM实现”旨在探讨如何结合这三种技术来实现对象关系映射(ORM),这是一种将数据库表与Java对象之间进行绑定的技术,简化了数据操作。 首先,我们来理解一下这三个概念: ...
在Android开发中,ORM(Object-Relational ...通过学习和理解这个项目,开发者不仅可以掌握自定义ORM实现的基本原理,还能了解到如何利用设计模式和反射API来优化Android应用的数据库操作,提升开发效率和代码质量。
5. **Java Reflection**:允许程序在运行时动态访问和修改对象的属性和方法,增强了代码的灵活性。 6. **Java Servlet和JavaServer Pages (JSP)**:用于构建Web应用程序的技术,Servlet处理服务器端逻辑,JSP负责...
以上只是Java JDK8源码中一部分关键知识点的概述,实际学习过程中,你会遇到更多关于编译器优化、垃圾收集算法、同步机制等方面的内容。通过深入阅读和理解源码,你可以提高自己的编程技巧,增强解决问题的能力,并...
在Java代码中,我们可以看到许多核心概念和技术。 1. 类与对象:Java是一种面向对象的语言,这意味着它基于类和对象。类是创建对象的蓝图,而对象是类的实例。类定义了数据成员(属性)和方法(功能),而对象则是...
熟悉AOP概念,学习如何利用AOP框架(如AspectJ、AspectWerkz)进行代码增强和模块化开发。 ### 18. 外部API与框架 了解并掌握常用的外部API和框架,如Log4J(日志)、Quartz(调度)、JGroups(网络组通信)、...
**JDK 1.5 API 全面解析** JDK(Java Development Kit)是Java编程语言的核心组件,包含了编译器、运行环境以及各种工具,是开发者进行...通过深入学习和实践,开发者可以充分利用这些特性,提高代码质量和维护性。
- **预热**:在应用程序启动初期执行反射操作,使JIT编译器有机会优化代码。 - **最小化反射使用**:尽可能减少反射的使用频率,特别是在性能关键的路径上。 #### 结论 Java反射机制虽然强大且灵活,但在性能方面...
Java 4还引入了反射(Reflection)API的改进,使开发者可以在运行时动态访问和修改类的属性、方法和构造器,这极大地增强了Java的灵活性和动态性。`java.lang.reflect`包中的类,如`Class`、`Method`和`Constructor`...
例如,Java中的`javassist`库和.NET框架的`Reflection.Emit` API,允许开发者直接构建和执行字节码序列,创建新的类、方法和属性。 3. **动态语言支持**:许多动态语言,如Python、Ruby和JavaScript,本身就支持...
**Java SDK 1.5 API中文文档概述** Java SDK 1.5,也被称为Java 5.0,是Java发展历程中的一个重要...通过深入研究这个文档,开发者能够充分利用Java 5的功能,提高代码质量,减少错误,提升程序的可维护性和可扩展性。