「java补偿机制实现」语言的补偿机制例子
今天给各位分享java补偿机制实现的知识,其中也会对语言的补偿机制例子进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
- 1、分析 Java I/O 的工作机制
- 2、Java实现机制是什么
- 3、java的"一次编译,到处运行"的机制是如何实现的?
- 4、事物补偿机制
- 5、Java的反射机制是什么,如何实现
- 6、java反射机制的实现原理
分析 Java I/O 的工作机制
网络 I/O 优化
网络 I/O 优化通常有一些基本处理原则
一个是减少网络交互的次数 要减少网络交互的次数通常我们在需要网络交互的两端会设置缓存 比如 Oracle 的 JDBC 驱动程序 就提供了对查询的 SQL 结果的缓存 在客户端和数据库端都有 可以有效的减少对数据库的访问 关于 Oracle JDBC 的内存管理可以参考《 Oracle JDBC 内存管理》 除了设置缓存还有一个办法是 合并访问请求 如在查询数据库时 我们要查 个 id 我可以每次查一个 id 也可以一次查 个 id 再比如在访问一个页面时通过会有多个 js 或 css 的文件 我们可以将多个 js 文件合并在一个 HTTP 链接中 每个文件用逗号隔开 然后发送到后端 Web 服务器根据这个 URL 链接 再拆分出各个文件 然后打包再一并发回给前端浏览器 这些都是常用的减少网络 I/O 的办法
减少网络传输数据量的大小 减少网络数据量的办法通常是将数据压缩后再传输 如 HTTP 请求中 通常 Web 服务器将请求的 Web 页面 gzip 压缩后在传输给浏览器 还有就是通过设计简单的协议 尽量通过读取协议头来获取有用的价值信息 比如在代理程序设计时 有 层代理和 层代理都是来尽量避免要读取整个通信数据来取得需要的信息
尽量减少编码 通常在网络 I/O 中数据传输都是以字节形式的 也就是通常要序列化 但是我们发送要传输的数据都是字符形式的 从字符到字节必须编码 但是这个编码过程是比较耗时的 所以在要经过网络 I/O 传输时 尽量直接以字节形式发送 也就是尽量提前将字符转化为字节 或者减少字符到字节的转化过程
根据应用场景设计合适的交互方式 所谓的交互场景主要包括同步与异步阻塞与非阻塞方式 下面将详细介绍
同步与异步
所谓同步就是一个任务的完成需要依赖另外一个任务时 只有等待被依赖的任务完成后 依赖的任务才能算完成 这是一种可靠的任务序列 要么成功都成功 失败都失败 两个任务的状态可以保持一致 而异步是不需要等待被依赖的任务完成 只是通知被依赖的任务要完成什么工作 依赖的任务也立即执行 只要自己完成了整个任务就算完成了 至于被依赖的任务最终是否真正完成 依赖它的任务无法确定 所以它是不可靠的任务序列 我们可以用打电话和发短信来很好的比喻同步与异步操作
在设计到 IO 处理时通常都会遇到一个是同步还是异步的处理方式的选择问题 因为同步与异步的 I/O 处理方式对调用者的影响很大 在数据库产品中都会遇到这个问题 因为 I/O 操作通常是一个非常耗时的操作 在一个任务序列中 I/O 通常都是性能瓶颈 但是同步与异步的处理方式对程序的可靠性影响非常大 同步能够保证程序的可靠性 而异步可以提升程序的性能 必须在可靠性和性能之间做个平衡 没有完美的解决办法
阻塞与非阻塞
阻塞与非阻塞主要是从 CPU 的消耗上来说的 阻塞就是 CPU 停下来等待一个慢的操作完成 CPU 才接着完成其它的事 非阻塞就是在这个慢的操作在执行时 CPU 去干其它别的事 等这个慢的操作完成时 CPU 再接着完成后续的操作 虽然表面上看非阻塞的方式可以明显的提高 CPU 的利用率 但是也带了另外一种后果就是系统的线程切换增加 增加的 CPU 使用时间能不能补偿系统的切换成本需要好好评估
两种的方式的组合
组合的方式可以由四种 分别是 同步阻塞 同步非阻塞 异步阻塞 异步非阻塞 这四种方式都对 I/O 性能有影响 下面给出分析 并有一些常用的设计用例参考
表 四种组合方式
组合方式
性能分析
同步阻塞
最常用的一种用法 使用也是最简单的 但是 I/O 性能一般很差 CPU 大部分在空闲状态
同步非阻塞
提升 I/O 性能的常用手段 就是将 I/O 的阻塞改成非阻塞方式 尤其在网络 I/O 是长连接 同时传输数据也不是很多的情况下 提升性能非常有效 这种方式通常能提升 I/O 性能 但是会增加 CPU 消耗 要考虑增加的 I/O 性能能不能补偿 CPU 的消耗 也就是系统的瓶颈是在 I/O 还是在 CPU 上
异步阻塞
这种方式在分布式数据库中经常用到 例如在网一个分布式数据库中写一条记录 通常会有一份是同步阻塞的记录 而还有两至三份是备份记录会写到其它机器上 这些备份记录通常都是采用异步阻塞的方式写 I/O 异步阻塞对网络 I/O 能够提升效率 尤其像上面这种同时写多份相同数据的情况
异步非阻塞
这种组合方式用起来比较复杂 只有在一些非常复杂的分布式情况下使用 像集群之间的消息同步机制一般用这种 I/O 组合方式 如 Cassandra 的Gossip 通信机制就是采用异步非阻塞的方式 它适合同时要传多份相同的数据到集群中不同的机器 同时数据的传输量虽然不大 但是却非常频繁 这种网络 I/O 用这个方式性能能达到最高
虽然异步和非阻塞能够提升 I/O 的性能 但是也会带来一些额外的性能成本 例如会增加线程数量从而增加 CPU 的消耗 同时也会导致程序设计的复杂度上升 如果设计的不合理的话反而会导致性能下降 在实际设计时要根据应用场景综合评估一下
下面举一些异步和阻塞的操作实例
在 Cassandra 中要查询数据通常会往多个数据节点发送查询命令 但是要检查每个节点返回数据的完整性 所以需要一个异步查询同步结果的应用场景 部分代码如下
清单 异步查询同步结果
class AsyncResult implements IAsyncResult{
private byte[] result_;
private AtomicBoolean done_ = new AtomicBoolean(false)
private Lock lock_ = new ReentrantLock()
private Condition condition_;
private long startTime_;
public AsyncResult(){
condition_ = lock_ newCondition() // 创建一个锁
startTime_ = System currentTimeMillis()
}
/*** 检查需要的数据是否已经返回 如果没有返回阻塞 */
public byte[] get(){
lock_ lock()
try{
if (!done_ get()){condition_ await() }
}catch (InterruptedException ex){
throw new AssertionError(ex)
}finally{lock_ unlock() }
return result_;
}
/*** 检查需要的数据是否已经返回 */
public boolean isDone(){return done_ get() }
/*** 检查在指定的时间内需要的数据是否已经返回 如果没有返回抛出超时异常 */
public byte[] get(long timeout TimeUnit tu) throws TimeoutException{
lock_ lock()
try{ boolean bVal = true;
try{
if ( !done_ get() ){
long overall_timeout = timeout (System currentTimeMillis() startTime_)
if(overall_timeout )// 设置等待超时的时间
bVal = condition_ await(overall_timeout TimeUnit MILLISECONDS)
else bVal = false;
}
}catch (InterruptedException ex){
throw new AssertionError(ex)
}
if ( !bVal !done_ get() ){// 抛出超时异常
throw new TimeoutException( Operation timed out )
}
}finally{lock_ unlock() }
return result_;
}
/*** 该函数拱另外一个线程设置要返回的数据 并唤醒在阻塞的线程 */
public void result(Message response){
try{
lock_ lock()
if ( !done_ get() ){
result_ = response getMessageBody() // 设置返回的数据
done_ set(true)
condition_ signal() // 唤醒阻塞的线程
}
}finally{lock_ unlock() }
}
}
总结
lishixinzhi/Article/program/Java/hx/201311/26096
Java实现机制是什么
将你编写的
程序编译
成
字节码
格式,然后运行在
java
虚拟机
上,不同平台有不同平台的
java
虚拟机
又称
jvm
java的"一次编译,到处运行"的机制是如何实现的?
JVM是一个java虚拟机,所谓的java虚拟机就是和普通的虚拟机一样,拥有自己的CPU,RAM之类的。我们所使用的操作系统是Windows的操作系统,Windows操作系统支持的可执行文件是EXE文件,也就是说在Windows的操作系统上只有EXE的文件是可以直接被操作系统解释为底层机器语言并进行运行的。而java虚拟机可以支持的是.class的可执行文件,在java的虚拟机中遇到.class的文件就可以直接翻译成java虚拟机所能是别的底层机器语言并进行执行。这就是JVM的机制,正是因为java的这种机制才实现了java的跨平台,在不同的平台上安装能够在相应平台上运行的虚拟机,然后在java虚拟机中运行java的源程序,“一次编译,多次执行”就此实现了。
所以java的跨平台是离不开虚拟机的支持的。虚拟机充当着java源程序和操作系统之间的中间,不同的操作系统只需要寻找相应的中介就可以实现在不同的操作系统上运行。而java的编译只是吧.java文件编译为.class字节码文件而已,然后把字节码交给虚拟机去执行。
虚拟机在执行的时候是读一句字节码文件人后解释一句给操作系统听,这就是为什么java是解释型的语言。
所谓的编译型的语言是指这种语言被编译之后生成的是可以直接供操作系统执行的010101文件,像C,C++都是编译型的,java因为中间有JVM这么个东西所以是解释型的。
事物补偿机制
事物补偿即在事物链中的任何一个正向事物操作,都必须存在一个完全符合回滚规则的可逆事物。如果是一个完整的事物链,则必须事务链中的每一个业务服务和操作都有对应的可逆服务。对于Service服务,也不容易实现前面讨论过的通过DTC或XA机制实现的跨应用和资源的事务管理,建立跨资源的事务上下文。因此也较难以实现真正的预提交和正式提交的分离。
实时一致性和最终一致性,如果需要的是最终一致性,那么base策略中的基于消息的最终一致性是比较好的解决方案。这种方案真正实现了两个服务的真正解耦,解耦的关键是异步消息和消息持久化机制。
Java的反射机制是什么,如何实现
Java中的反射机制,通俗点解释就是能够在程序运行中动态获取到内存中任一对象的信息,这些信息包括对象所属类、类中的方法和属性、以及它们的访问控制域和返回值类型等等,还可以通过反射动态调用对象中的方法,而不管该方法的访问域是私有或是公开,包括构造方法,还能实现动态代理等。总之,反射能够破坏掉JAVA类本身的封装性,进而获取其私有的或公开的信息,也就能突破封装进而调用私有的或公开的方法。
实现的话就是通过反射接口,JAVA把反射相关的类接口都封装在了java.lang.reflect这个包中,你可以研究下这个包中的类,对于类的每一个属性,如变量、方法,构造方法,这个包中都就与之相对应的类,通过这个类就可以操作这个属性了。
java反射很强大,但也很危险,在实际开发中应少用或不用,在必要用之时,往往也能解决你遇到的问题。
java反射机制的实现原理
反射机制:所谓的反射机制就是java语言在运行时拥有一项自观的能力。通过这种能力可以彻底的了解自身的情况为下一步的动作做准备。下面具体介绍一下java的反射机制。这里你将颠覆原来对java的理解。
Java的反射机制的实现要借助于4个类:class,Constructor,Field,Method;其中class代表的时类对 象,Constructor-类的构造器对象,Field-类的属性对象,Method-类的方法对象。通过这四个对象我们可以粗略的看到一个类的各个组 成部分。
Class:程序运行时,java运行时系统会对所有的对象进行运行时类型的处理。这项信息记录了每个对象所属的类,虚拟机通常使用运行时类型信息选择正 确的方法来执行(摘自:白皮书)。但是这些信息我们怎么得到啊,就要借助于class类对象了啊。在Object类中定义了getClass()方法。我 们可以通过这个方法获得指定对象的类对象。然后我们通过分析这个对象就可以得到我们要的信息了。
比如:ArrayList arrayList;
Class clazz = arrayList.getClass();
然后我来处理这个对象clazz。
当然了Class类具有很多的方法,这里重点将和Constructor,Field,Method类有关系的方法。
Reflection 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说“自审”,并能直接操作程序的内部属性。Java 的这一能力在实际应用中也许用得不是很多,但是个人认为要想对java有个更加深入的了解还是应该掌握的。
1.检测类:
reflection的工作机制
考虑下面这个简单的例子,让我们看看 reflection 是如何工作的。
import java.lang.reflect.*;
public class DumpMethods {
public static void main(String args[]) {
try {
Class c = Class.forName(args[0]);
Method m[] = c.getDeclaredMethods();
for (int i = 0; i m.length; i++)
System.out.println(m[i].toString());
} catch (Throwable e) {
System.err.println(e);
}
}
}
按如下语句执行:
java DumpMethods java.util.ArrayList
这个程序使用 Class.forName 载入指定的类,然后调用 getDeclaredMethods 来获取这个类中定义了的方法列表。java.lang.reflect.Methods 是用来描述某个类中单个方法的一个类。
Java类反射中的主要方法
对于以下三类组件中的任何一类来说 -- 构造函数、字段和方法 -- java.lang.Class 提供四种独立的反射调用,以不同的方式来获得信息。调用都遵循一种标准格式。以下是用于查找构造函数的一组反射调用:
Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公共构造函数,
Constructor[] getConstructors() -- 获得类的所有公共构造函数
Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的构造函数(与接入级别无关)
Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(与接入级别无关)
获得字段信息的Class 反射调用不同于那些用于接入构造函数的调用,在参数类型数组中使用了字段名:
Field getField(String name) -- 获得命名的公共字段
Field[] getFields() -- 获得类的所有公共字段
Field getDeclaredField(String name) -- 获得类声明的命名的字段
Field[] getDeclaredFields() -- 获得类声明的所有字段
用于获得方法信息函数:
Method getMethod(String name, Class[] params) -- 使用特定的参数类型,获得命名的公共方法
Method[] getMethods() -- 获得类的所有公共方法
Method getDeclaredMethod(String name, Class[] params) -- 使用特写的参数类型,获得类声明的命名的方法
Method[] getDeclaredMethods() -- 获得类声明的所有方法
使用 Reflection:
用于 reflection 的类,如 Method,可以在 java.lang.relfect 包中找到。使用这些类的时候必须要遵循三个步骤:第一步是获得你想操作的类的 java.lang.Class 对象。在运行中的 Java 程序中,用 java.lang.Class 类来描述类和接口等。
下面就是获得一个 Class 对象的方法之一:
Class c = Class.forName("java.lang.String");
这条语句得到一个 String 类的类对象。还有另一种方法,如下面的语句:
Class c = int.class;
或者
Class c = Integer.TYPE;
它们可获得基本类型的类信息。其中后一种方法中访问的是基本类型的封装类 (如 Intege ) 中预先定义好的 TYPE 字段。
第二步是调用诸如 getDeclaredMethods 的方法,以取得该类中定义的所有方法的列表。
一旦取得这个信息,就可以进行第三步了——使用 reflection API 来操作这些信息,如下面这段代码:
Class c = Class.forName("java.lang.String");
Method m[] = c.getDeclaredMethods();
System.out.println(m[0].toString());
它将以文本方式打印出 String 中定义的第一个方法的原型。
处理对象:
a.创建一个Class对象
b.通过getField 创建一个Field对象
c.调用Field.getXXX(Object)方法(XXX是Int,Float等,如果是对象就省略;Object是指实例).
例如:
import java.lang.reflect.*;
import java.awt.*;
class SampleGet {
public static void main(String[] args) {
Rectangle r = new Rectangle(100, 325);
printHeight(r);
}
static void printHeight(Rectangle r) {
Field heightField;
Integer heightValue;
Class c = r.getClass();
try {
heightField = c.getField("height");
heightValue = (Integer) heightField.get(r);
System.out.println("Height: " + heightValue.toString());
} catch (NoSuchFieldException e) {
System.out.println(e);
} catch (SecurityException e) {
System.out.println(e);
} catch (IllegalAccessException e) {
System.out.println(e);
}
}
}
安全性和反射:
在处理反射时安全性是一个较复杂的问题。反射经常由框架型代码使用,由于这一点,我们可能希望框架能够全面接入代码,无需考虑常规的接入限制。但是,在其它情况下,不受控制的接入会带来严重的安全性风险,例如当代码在不值得信任的代码共享的环境中运行时。
由于这些互相矛盾的需求,Java编程语言定义一种多级别方法来处理反射的安全性。基本模式是对反射实施与应用于源代码接入相同的限制:
从任意位置到类公共组件的接入
类自身外部无任何到私有组件的接入
受保护和打包(缺省接入)组件的有限接入
不过至少有些时候,围绕这些限制还有一种简单的方法。我们可以在我们所写的类中,扩展一个普通的基本类 java.lang.reflect.AccessibleObject 类。这个类定义了一种setAccessible方法,使我们能够启动或关闭对这些类中其中一个类的实例的接入检测。唯一的问题在于如果使用了安全性管理 器,它将检测正在关闭接入检测的代码是否许可了这样做。如果未许可,安全性管理器抛出一个例外。
下面是一段程序,在TwoString 类的一个实例上使用反射来显示安全性正在运行:
public class ReflectSecurity {
public static void main(String[] args) {
try {
TwoString ts = new TwoString("a", "b");
Field field = clas.getDeclaredField("m_s1");
// field.setAccessible(true);
System.out.println("Retrieved value is " +
field.get(inst));
} catch (Exception ex) {
ex.printStackTrace(System.out);
}
}
}
如果我们编译这一程序时,不使用任何特定参数直接从命令行运行,它将在field .get(inst)调用中抛出一个IllegalAccessException异常。如果我们不注释 field.setAccessible(true)代码行,那么重新编译并重新运行该代码,它将编译成功。最后,如果我们在命令行添加了JVM参数 -Djava.security.manager以实现安全性管理器,它仍然将不能通过编译,除非我们定义了ReflectSecurity类的许可权 限。
反射性能:(转录别人的啊)
反射是一种强大的工具,但也存在一些不足。一个主要的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于只直接执行相同的操作。
下面的程序是字段接入性能测试的一个例子,包括基本的测试方法。每种方法测试字段接入的一种形式 -- accessSame 与同一对象的成员字段协作,accessOther 使用可直接接入的另一对象的字段,accessReflection 使用可通过反射接入的另一对象的字段。在每种情况下,方法执行相同的计算 -- 循环中简单的加/乘顺序。
程序如下:
public int accessSame(int loops) {
m_value = 0;
for (int index = 0; index loops; index++) {
m_value = (m_value + ADDITIVE_VALUE) *
MULTIPLIER_VALUE;
}
return m_value;
}
public int acces
sReference(int loops) {
TimingClass timing = new TimingClass();
for (int index = 0; index loops; index++) {
timing.m_value = (timing.m_value + ADDITIVE_VALUE) *
MULTIPLIER_VALUE;
}
return timing.m_value;
}
public int accessReflection(int loops) throws Exception {
TimingClass timing = new TimingClass();
try {
Field field = TimingClass.class.
getDeclaredField("m_value");
for (int index = 0; index loops; index++) {
int value = (field.getInt(timing) +
ADDITIVE_VALUE) * MULTIPLIER_VALUE;
field.setInt(timing, value);
}
return timing.m_value;
} catch (Exception ex) {
System.out.println("Error using reflection");
throw ex;
}
}
在上面的例子中,测试程序重复调用每种方法,使用一个大循环数,从而平均多次调用的时间衡量结果。平均值中不包括每种方法第一次调用的时间,因此初始化时间不是结果中的一个因素。下面的图清楚的向我们展示了每种方法字段接入的时间:
图 1:字段接入时间 :
我们可以看出:在前两副图中(Sun JVM),使用反射的执行时间超过使用直接接入的1000倍以上。通过比较,IBM JVM可能稍好一些,但反射方法仍旧需要比其它方法长700倍以上的时间。任何JVM上其它两种方法之间时间方面无任何显著差异,但IBM JVM几乎比Sun JVM快一倍。最有可能的是这种差异反映了Sun Hot Spot JVM的专业优化,它在简单基准方面表现得很糟糕。反射性能是Sun开发1.4 JVM时关注的一个方面,它在反射方法调用结果中显示。在这类操作的性能方面,Sun 1.4.1 JVM显示了比1.3.1版本很大的改进。
如果为为创建使用反射的对象编写了类似的计时测试程序,我们会发现这种情况下的差异不象字段和方法调用情况下那么显著。使用newInstance()调 用创建一个简单的java.lang.Object实例耗用的时间大约是在Sun 1.3.1 JVM上使用new Object()的12倍,是在IBM 1.4.0 JVM的四倍,只是Sun 1.4.1 JVM上的两部。使用Array.newInstance(type, size)创建一个数组耗用的时间是任何测试的JVM上使用new type[size]的两倍,随着数组大小的增加,差异逐步缩小。随着jdk6.0的推出,反射机制的性能也有了很大的提升。期待中….
总结:
Java语言反射提供一种动态链接程序组件的多功能方法。它允许程序创建和控制任何类的对象(根据安全性限制),无需提前硬编码目标类。这些特性使得反射 特别适用于创建以非常普通的方式与对象协作的库。例如,反射经常在持续存储对象为数据库、XML或其它外部格式的框架中使用。Java reflection 非常有用,它使类和数据结构能按名称动态检索相关信息,并允许在运行着的程序中操作这些信息。Java 的这一特性非常强大,并且是其它一些常用语言,如 C、C++、Fortran 或者 Pascal 等都不具备的。
但反射有两个缺点。第一个是性能问题。用于字段和方法接入时反射要远慢于直接代码。性能问题的程度取决于程序中是如何使用反射的。如果它作为程序运行中相 对很少涉及的部分,缓慢的性能将不会是一个问题。即使测试中最坏情况下的计时图显示的反射操作只耗用几微秒。仅反射在性能关键的应用的核心逻辑中使用时性 能问题才变得至关重要。
许多应用中更严重的一个缺点是使用反射会模糊程序内部实际要发生的事情。程序人员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术会带来维护问 题。反射代码比相应的直接代码更复杂,正如性能比较的代码实例中看到的一样。解决这些问题的最佳方案是保守地使用反射——仅在它可以真正增加灵活性的地方 ——记录其在目标类中的使用。
一下是对应各个部分的例子:
具体的应用:
1、 模仿instanceof 运算符号
class A {}
public class instance1 {
public static void main(String args[])
{
try {
Class cls = Class.forName("A");
boolean b1
= cls.isInstance(new Integer(37));
System.out.println(b1);
boolean b2 = cls.isInstance(new A());
System.out.println(b2);
}
catch (Throwable e) {
System.err.println(e);
}
}
}
2、 在类中寻找指定的方法,同时获取该方法的参数列表,例外和返回值
import java.lang.reflect.*;
public class method1 {
private int f1(
Object p, int x) throws NullPointerException
{
if (p == null)
throw new NullPointerException();
return x;
}
public static void main(String args[])
{
try {
Class cls = Class.forName("method1");
Method methlist[]
= cls.getDeclaredMethods();
for (int i = 0; i methlist.length;
i++)
Method m = methlist[i];
System.out.println("name
= " + m.getName());
System.out.println("decl class = " +
m.getDeclaringClass());
Class pvec[] = m.getParameterTypes();
for (int j = 0; j pvec.length; j++)
System.out.println("
param #" + j + " " + pvec[j]);
Class evec[] = m.getExceptionTypes();
for (int j = 0; j evec.length; j++)
System.out.println("exc #" + j
+ " " + evec[j]);
System.out.println("return type = " +
m.getReturnType());
System.out.println("-----");
}
}
catch (Throwable e) {
System.err.println(e);
}
}
}
3、 获取类的构造函数信息,基本上与获取方法的方式相同
import java.lang.reflect.*;
public class constructor1 {
public constructor1()
{
}
protected constructor1(int i, double d)
{
}
public static void main(String args[])
{
try {
Class cls = Class.forName("constructor1");
Constructor ctorlist[]
= cls.getDeclaredConstructors();
for (int i = 0; i ctorlist.length; i++) {
Constructor ct = ctorlist[i];
System.out.println("name
= " + ct.getName());
System.out.println("decl class = " +
ct.getDeclaringClass());
Class pvec[] = ct.getParameterTypes();
for (int j = 0; j pvec.length; j++)
System.out.println("param #"
+ j + " " + pvec[j]);
Class evec[] = ct.getExceptionTypes();
for (int j = 0; j evec.length; j++)
System.out.println(
"exc #" + j + " " + evec[j]);
System.out.println("-----");
}
}
catch (Throwable e) {
System.err.println(e);
}
}
}
4、 获取类中的各个数据成员对象,包括名称。类型和访问修饰符号
import java.lang.reflect.*;
public class field1 {
private double d;
public static final int i = 37;
String s = "testing";
public static void main(String args[])
{
try {
Class cls = Class.forName("field1");
Field fieldlist[]
= cls.getDeclaredFields();
for (int i
= 0; i fieldlist.length; i++) {
Field fld = fieldlist[i];
System.out.println("name
= " + fld.getName());
System.out.println("decl class = " +
fld.getDeclaringClass());
System.out.println("type
= " + fld.getType());
int mod = fld.getModifiers();
System.out.println("modifiers = " +
Modifier.toString(mod));
System.out.println("-----");
}
}
catch (Throwable e) {
System.err.println(e);
}
}
}
5、 通过使用方法的名字调用方法
import java.lang.reflect.*;
public class method2 {
public int add(int a, int b)
{
return a + b;
}
public static void main(String args[])
{
try {
Class cls = Class.forName("method2");
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
Method meth = cls.getMethod(
"add", partypes);
method2 methobj = new method2();
Object arglist[] = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
Object retobj
= meth.invoke(methobj, arglist);
Integer retval = (Integer)retobj;
System.out.println(retval.intValue());
}
catch (Throwable e) {
System.err.println(e);
}
}
}
6、 创建新的对象
import java.lang.reflect.*;
public class constructor2 {
public constructor2()
{
}
public constructor2(int a, int b)
{
System.out.println(
"a = " + a + " b = " + b);
}
public static void main(String args[])
{
try {
Class cls = Class.forName("constructor2");
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
Constructor ct
= cls.getConstructor(partypes);
Object arglist[] = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
Object retobj = ct.newInstance(arglist);
}
catch (Throwable e) {
System.err.println(e);
}
}
}
7、 变更类实例中的数据的值
import java.lang.reflect.*;
public class field2 {
public double d;
public static void main(String args[])
{
try {
Class cls = Class.forName("field2");
Field fld = cls.getField("d");
field2 f2obj = new field2();
System.out.println("d = " + f2obj.d);
fld.setDouble(f2obj, 12.34);
System.out.println("d = " + f2obj.d);
}
catch (Throwable e) {
System.err.println(e);
}
}
}
使用反射创建可重用代码:
1、 对象工厂
Object factory(String p) {
Class c;
Object o=null;
try {
c = Class.forName(p);// get class def
o = c.newInstance(); // make a new one
} catch (Exception e) {
System.err.println("Can't make a " + p);
}
return o;
}
public class ObjectFoundry {
public static Object factory(String p)
throws ClassNotFoundException,
InstantiationException,
IllegalAccessException {
Class c = Class.forName(p);
Object o = c.newInstance();
return o;
}
}
2、 动态检测对象的身份,替代instanceof
public static boolean
isKindOf(Object obj, String type)
throws ClassNotFoundException {
// get the class def for obj and type
Class c = obj.getClass();
Class tClass = Class.forName(type);
while ( c!=null ) {
if ( c==tClass ) return true;
c = c.getSuperclass();
}
return false;
}
java补偿机制实现的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于语言的补偿机制例子、java补偿机制实现的信息别忘了在本站进行查找喔。