- 浏览: 779636 次
- 性别:
- 来自: 杭州
-
文章分类
最新评论
-
Fanatic357:
同问,请问这个 曲线 是用什么工具 监测得到的?
RocketMQ性能压测分析 -
sunshine_love:
8核 16G, 单master TPS 4w+,2m-2s- ...
RocketMQ性能压测分析 -
assertmyself:
很好,,获益良多!
jstack和线程dump分析 -
zhaoxiaoxiao:
非常赞,帮助理解了问题。今天也是遇到了这样的问题
hessian序列化bug -
wjg_java:
打不开 宕机了
博客停止更新
先说一下java class的加载机制和与class文件的关系:Java 程序的工作机制: Java 对象都以单独的 class 文件存在, java 虚拟机将其载入并执行其虚拟机指令。
class 的加载与实例化
java 虚拟机根据 class path 来查找 java 对象,而虚拟机的 class path 又分为三层:
bootstrap : sun.boot.class.path
extension: java.ext.dirs
application: java.class.path
三个 class path 各有对应的 classloader 。由上而下形成父子关系
当程序中调用 new 指令,或者 ClassLoader.load 方法时。其顺序如下:
1. 首先查看 application 的 classloader 中是否已有对应的 class 缓存,如果有则返回,并根据 class 分配内存。如果没有,接下一步。
2. 首先查看 extension 的 classloader 中是否已有对应的 class 缓存,如果有则返回,并根据 class 分配内存。如果没有,接下一步。
3. 首先查看 bootstrap 的 classloader 中是否已有对应的 class 缓存,如果有则返回,并根据 class 分配内存。如果没有,接下一步。
4. 由 bootstrap 的 classloader 在其 class path 中试图加载该 class ,如果有,则将该 class 放入 cache 中,并返回。如果没有,接下一步。
5. 由 extension 的 classloader 在其 class path 中试图加载该 class ,如果有,则将该 class 放入 cache 中,并返回。如果没有,接下一步。
6. 由 application 的 classloader 在其 class path 中试图加载该 class ,如果有,则将该 class 放入 cache 中,并返回。如果没有,则抛出 ClassNotFound 的 exception 。
每个 java 虚拟机都在其启动时产生一个唯一的 class heap ,并把所有的 class instance 都分配在其中。其中每个类实例的信息又分两部分, fields 域和 methods 域。每个类实例各自拥有 fields ,但同一个类的不同实例共享 methods
java 反射的处理
简单例子代码:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; import java.io.IOException; public class Main { public static void main(String[] args){ TempImpl t1 = new TempImpl("temp1"); try { Method t1Talk = t1.getClass().getMethod("Talk", new Class[0]) ; t1Talk.invoke(t1, null); } catch (NoSuchMethodException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } catch (IllegalAccessException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } catch (InvocationTargetException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } try { System.in.read(); } catch (IOException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } } } |
复杂例子代码:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; import java.io.IOException; public class Main { public static void main(String[] args){ TempImpl t1 = new TempImpl("temp1"); TempImpl t2 = new TempImpl("temp2"); Temp2 temp2 = new Temp2(); try { Method t1Talk = t1.getClass().getMethod("Talk", new Class[0]) ; Method t2Talk = t2.getClass().getMethod("Talk", new Class[0]) ; t1Talk.invoke(t2, null); t2Talk.invoke(t1, null); if(t1Talk.equals(t2Talk)){ System.out.println("equals"); }else{ System.out.println("not equals"); } if(t1Talk==t2Talk){ System.out.println("ref equals"); }else{ System.out.println("ref not equals"); } t2Talk.invoke(temp2, null); } catch (NoSuchMethodException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } catch (IllegalAccessException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } catch (InvocationTargetException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } try { System.in.read(); } catch (IOException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } } } |
分析: java 虚拟机把每个 methods 当作一个执行单元。该执行单元带有两种签名:类签名和属性签名( public , static 等)。 反射的第一步,验证签名的合法性。验证通过后,顺序执行该 method 中的指令,当需要访问类实例的 fields 和传入参数时,由虚拟机注入。
动态代理
一个简单例子代码:
研究 JDK 源代码,发现在 Proxy 的 sun 实现中调用了 sun.misc.ProxyGenerator 类的 generateProxyClass( proxyName, interfaces) 方法,其返回值为 byte[] 和 class 文件的内存类型一致。于是做如下试验:
public class ProxyClassFile{ public static void main(String[] args){ String proxyName = "TempProxy"; TempImpl t = new TempImpl("proxy"); Class[] interfaces =t.getClass().getInterfaces(); byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces); File f = new File("classes/TempProxy.class"); try { FileOutputStream fos = new FileOutputStream(f); fos.write(proxyClassFile); fos.flush(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } catch (IOException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } } } |
运行该类,到 class 文件夹下,利用反编译技术,发现原来其采用了代码生产技术:
public interface Temp{ public void Talk(); public void Run(); } |
import java.lang.reflect.*; public final class TempProxy extends Proxy implements Temp{ private static Method m4; private static Method m2; private static Method m0; private static Method m3; private static Method m1; public TempProxy(InvocationHandler invocationhandler) { super(invocationhandler); } public final void Run() { try { h.invoke(this, m4, null); return; } catch(Error _ex) { } catch(Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final String toString(){ try{ return (String)h.invoke(this, m2, null); } catch(Error _ex) { } catch(Throwable throwable) { throw new UndeclaredThrowableException(throwable); } return ""; } public final int hashCode() { try { return ((Integer)h.invoke(this, m0, null)).intValue(); } catch(Error _ex) { } catch(Throwable throwable){ throw new UndeclaredThrowableException(throwable); } return 123; } public final void Talk(){ try{ h.invoke(this, m3, null); return; } catch(Error _ex) { } catch(Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final boolean equals(Object obj) { try { return ((Boolean)h.invoke(this, m1, new object[{obj})).booleanValue(); } catch(Error _ex) { } catch(Throwable throwable) { throw new UndeclaredThrowableException(throwable); } return false; } static{ try{ m4 = Class.forName("Temp").getMethod("Run", new Class[0]); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); m3 = Class.forName("Temp").getMethod("Talk", new Class[0]); m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); } catch(NoSuchMethodException nosuchmethodexception) { throw new NoSuchMethodError(nosuchmethodexception.getMessage()); } catch(ClassNotFoundException classnotfoundexception) { throw new NoClassDefFoundError(classnotfoundexception.getMessage()); } } } |
发表评论
-
dubbo问题总结
2012-03-14 10:00 3004任何诡异的现象必然能找到问题原因,程序是不会骗人的 ... -
memcached客户端源码分析
2011-09-08 17:28 19996memcached的java客户端有好 ... -
说说单例模式
2011-05-23 11:12 3389单例模式?多么简单!也许吧,可是要通过简单的现象, ... -
jstack和线程dump分析
2011-05-12 13:48 180256一:jstack jstack命令的语法格式: js ... -
说说new Integer和Integer.valueOf
2010-11-11 15:04 6622看看这两个语句 Integer a=new Integ ... -
线程安全总结(二)
2010-11-11 12:36 5644关于线程安全总结(-)请看 http://www.iteye ... -
java线程安全总结
2010-11-09 20:48 15683最近想将java基 ... -
hadoop架构
2010-09-07 19:41 2718该文章我转自IBM开发者社区 ... -
HashMap深入分析
2010-09-03 19:36 5852java.util.HashMap是很常见的 ... -
CountDownLatch
2010-09-02 20:03 2990java的并发包真 ... -
ThreadPoolExecutor相关类的分析
2010-09-02 19:27 4628一:ThreadPoolExecutor ... -
随便说说
2010-09-01 19:29 2122这两天给系统 ... -
一波三折的rmi调用
2010-08-18 18:02 9883很久以前写了基于rmi的分布式java程序,现 ... -
java内存查看与分析
2010-08-07 17:03 22533业界有很多强 ... -
java动态代理之cglib
2010-06-22 17:27 2830cglib是一个 ... -
java动态代理随笔二
2010-06-22 16:29 1902jdk的动态代 ... -
关于hashcode和equals
2010-04-19 14:58 3418前几天有个同事问我,String a=" ... -
建设银行对接(五)
2010-02-09 17:34 2584public static void testVerify ... -
建设银行对接(四)
2010-02-09 17:32 3141上接“建设银行对接(三)”,javaeye的文章字数限制也太少 ... -
建设银行对接(三)
2010-02-09 17:24 3518前面两章请见我的博客 对建行返回的数据进行数字签名 ...
相关推荐
而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更需要学习的是其底层是怎么样的一个原理,而AOP的原理是java的动态代理机制,所以本篇随笔是对java的动态机制进行一个回顾。...
7. **反射与动态代理**:Java的反射机制允许在运行时检查和修改程序行为,动态代理则提供了创建动态类型和接口实现的能力,这些在框架和库的开发中非常常见。 8. **安全机制**:JVM也扮演着安全管理的角色,书中...
Java驴友社交系统是一个专为户外旅行爱好者设计的社交平台,它通过Java技术栈实现,提供了客户端和服务端的完整源码,便于学习和研究。在这个系统中,开发者可以深入理解如何构建一个完整的社交网络应用,涉及到的...
所以把休闲娱乐代理售票管理与现在网络相结合,利用java技术建设休闲娱乐代理售票系统,实现休闲娱乐代理售票的信息化。则对于进一步提高休闲娱乐代理售票管理发展,丰富休闲娱乐代理售票管理经验能起到不少的促进...
2. **Java脚本**(通常指的是JavaScript):是一种广泛使用的客户端脚本语言,主要用于网页交互、动态内容生成和Web应用开发。 3. **Git**:是一种分布式版本控制系统,用于追踪对文件的修改,便于多人协作开发和...
- 一站式支付解决方案,统一下单接口,支持支付宝、微信、网银等多种支付方式。不涉及业务的纯粹的支付平台。 - 统一下单(统一下单接口、统一扫码)、订单管理、数据分析、财务报表、商户管理、渠道管理、对账系统...
Spring MVC 是一个基于 Java 的轻量级 Web 开发框架,它是 Spring 框架的一部分,主要用于构建 MVC(Model-View-Controller)模式的 Web 应用程序。在使用 Spring MVC 进行开发时,需要引入一系列的依赖 JAR 包来...