区别如下:
1:首先new出来的对象我们无法访问其中的私有属性,但是通过反射出来的对象我们可以通过setAccessible()方法
来访问其中的私有属性。
2:在使用new创建一个对象实例的时候必须知道类名,但是通过反射创建对象有时候不需要知道类名也可以(网
上其他帖子也有相似观点但是都没有说明其原因,下面我就分析分析。
首先要使用反射创建对象必须要得到类的Class对象,至于怎么得到这个Class对象,有很多方法例如对于类A及其
实例str_a来说可以使用A.class(),str_a.getClass()或者Class.forName("A")
。这几种方法无一例外都需要使用到类名来
获取
类
Class
对象,但是
有一种
方式是不需要类名的,那就是
jdk
的动态
代理。动态代理是一种在运行期动态生成字节
码并
转换成代理
类
Class
对象的一种方
法
,AOP连同
IOC
一起是
spring
的核心。我们下面就来看看源码:
首先jvm在其内部通过函数ProxyGenerator.generateProxyClass()方法来生成代理对象的字节码文件(其实就没有具
体文件,一切都是在内存中,暂时就这么叫吧),然后defineClass0()函数利用之前生成的二进制字节码文件来创建
类Class对象,并顺便为代理类命名(proxyName是在字节码文件生成之前自己命名的),经过这个过程我们就可以在不
知道类名的情况下得到了类Class对象了,然后就可以使用反射来获取对象实例了(这其中牵扯到类加载的加载过程,
具体内容请详看有关资料)
(其实上面所说的几种利用类名获取类Class对象的方法也是利用了类加载机制,也是使用了defineClass()函数,但
是不同的是他们的字节码文件不是动态生成的而是利javac生成或者从网络,jar包上获取到的,接着使用类名找到相应
的二进制字节码文件,然后利用defineclass()函数生成Class对象,所以类名在这几种方法中起的作用就是定位字节码文
件的位置从而找到它,而动态代理是动态生成字节码文件,是一种典型的随用随生成的机制,也就不存在定位二进制
字节码文件位置这个问题了)。排版真实难用,凑合看吧