Class.newInstance()与new、Constructor.newInstance()的区别
在初始化一个类,生成一个实例的时候,newInstance() 和 new 有什么区别?
用newInstance与用new是区别的, 区别在于创建对象的方式不一样,前者是使用类加载机制,那么为什么会有两种创建对象方式?这个就要从可伸缩、可扩展,可重用等软件思想上解释了。
Java中工厂模式经常使用newInstance来创建对象,因此从为什么要使用工厂模式上也可以找到具体答案。
例如:
- Class c = Class.forName(“A”);
- factory = (AInterface)c.newInstance();
其中AInterface是A的接口,如果下面这样写,你可能会理解:
- String className = "A";
- Class c = Class.forName(className);
- factory = (AInterface)c.newInstance();
进一步,如果下面写,你可能会理解:
- String className = readfromXMlConfig;
- //从xml 配置文件中获得字符串
- Class c = Class.forName(className);
- factory = (AInterface)c.newInstance();
上面代码就消灭了A类名称,优点:无论A类怎么变化,上述代码不变,甚至可以更换A的兄弟类B , C , D....等,只要他们继承Ainterface就可以。
从jvm的角度看,我们使用new的时候,这个要new的类可以没有加载;
但是使用newInstance时候,就必须保证:
1、这个类已经加载;
2、这个类已经连接了。
而完成上面两个步骤的正是class的静态方法forName方法,这个静态方法调用了启动类加载器(就是加载Java API的那个加载器)。
有了上面jvm上的理解,那么我们可以这样说, newInstance实际上是把new这个方式分解为两步,即,首先调用class的加载方法加载某个类,然后实例化。
这样分步的好处是显而易见的。new者,包括用A.class,在编译期已经确定,不可能在运行期变更,一旦要变更必须改变这部分代码,而newInstance者,Class.forName(String)的参数可以在运行期配置,而无须改动代码, 我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了我们降耦的手段。
newInstance: 弱类型。低效率。 只能调用无参构造。
new: 强类型。相对高效。能调用任何public构造。
newInstance() 的参数版本与无参数版本详解
Class.newInstance()
Constructor.newInstance()
以下对两种调用方式给以比较说明:
Class.newInstance() 只能够调用无参的构造函数,即默认的构造函数;
Constructor.newInstance() 可以根据传入的参数,调用任意构造构造函数。
Class.newInstance() 抛出所有由被调用构造函数抛出的异常。
Class.newInstance() 要求被调用的构造函数是可见的,也即必须是public类型的;
Constructor.newInstance() 在特定的情况下,可以调用私有的构造函数。
Class A(被调用的示例):
- public class A {
- private A() {
- System.out.println("A's constructor is called.");
- }
- private A(int a, int b) {
- System.out.println("a:" + a + " b:" + b);
- }
- }
Class B(调用者):
- public class B {
- public static void main(String[] args) {
- B b=new B();
- out.println("通过Class.NewInstance()调用私有构造函数:");
- b.newInstanceByClassNewInstance();
- out.println("通过Constructor.newInstance()调用私有构造函数:");
- b.newInstanceByConstructorNewInstance();
- }
- /*通过Class.NewInstance()创建新的类示例*/
- private void newInstanceByClassNewInstance(){
- try {/*当前包名为reflect,必须使用全路径*/
- A a=(A)Class.forName("reflect.A").newInstance();
- } catch (Exception e) {
- out.println("通过Class.NewInstance()调用私有构造函数【失败】");
- }
- }
- /*通过Constructor.newInstance()创建新的类示例*/
- private void newInstanceByConstructorNewInstance(){
- try {/*可以使用相对路径,同一个包中可以不用带包路径*/
- Class c=Class.forName("A");
- /*以下调用无参的、私有构造函数*/
- Constructor c0=c.getDeclaredConstructor();
- c0.setAccessible(true);
- A a0=(A)c0.newInstance();
- /*以下调用带参的、私有构造函数*/
- Constructor c1=c.getDeclaredConstructor(new Class[]{int.class,int.class});
- c1.setAccessible(true);
- A a1=(A)c1.newInstance(new Object[]{5,6});
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
输入结果如下:
通过Class.NewInstance()调用私有构造函数:
通过Class.NewInstance()调用私有构造函数【失败】
通过Constructor.newInstance()调用私有构造函数:
A's constructor is called.
a:5 b:6
说明方法newInstanceByClassNewInstance调用失败,而方法newInstanceByConstructorNewInstance则调用成功。
如果被调用的类的构造函数为默认的构造函数,采用Class.newInstance()则是比较好的选择,
一句代码就OK;如果需要调用类的带参构造函数、私有构造函数,
就需要采用Constractor.newInstance(),两种情况视使用情况而定。
不过Java Totorial中推荐采用Constractor.newInstance()。
Class.newInstance()与new、Constructor.newInstance()的区别相关推荐
- 面试高频——JUC并发工具包快速上手(超详细总结)
目录 一.什么是JUC 二.基本知识 2.1.进程和线程 2.2.Java默认有两个进程 2.3.Java能够开启线程吗? 2.4.并发和并行 2.5.线程的状态 2.6.wait和sleep的区别 ...
- 【转】Java基础知识整理
本博文内容参考相关博客以及<Java编程思想>整理而成,如有侵权,请联系博主. 转载请注明出处:http://www.cnblogs.com/BYRans/ PDF版下载链接:<Ja ...
- java 基础知识总结
Java基础知识总结 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java语言代码把思 ...
- javaSE知识点汇总
javaSE知识点汇总 Java基础知识精华部分 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实 ...
- 原创 | 万万没想到,JVM内存结构的面试题可以问的这么难?
△Hollis, 一个对Coding有着独特追求的人△ 这是Hollis的第 223 篇原创分享 作者 l Hollis 来源 l Hollis(ID:hollischuang) 在我的博客中,之前有 ...
- 【转】java基础知识总结
Java基础知识总结 本博文内容参考相关博客以及<Java编程思想>整理而成,如有侵权,请联系博主. 转载请注明出处:http://www.cnblogs.com/BYRans/ PDF版 ...
- java枚举的线程安全及序列化
原文链接:https://www.cnblogs.com/z00377750/p/9177097.html https://www.cnblogs.com/chiclee/p/9097772.html ...
- Spring代理模式及AOP基本术语
一.代理模式: 静态代理.动态代理 动态代理和静态代理区别?? 解析:静态代理需要手工编写代理类,代理类引用被代理对象. 动态代理是在内存中构建的,不需要手动编写代理类 代理的目的:是为了在原有的方法 ...
- Java学习笔记基础(下)
基本数据类型对象包装类:是按照面向对象思想将基本数据类型封装成了对象. 好处: 1:可以通过对象中的属性和行为操作基本数据. 2:可以实现基本数据类型和字符串之间的转换. 关键字 对应的类名 by ...
最新文章
- 【Eclipse】 Eclipse 中JPEGEncodeParam 错误波浪线问题
- PAT乙级 1005继续3n+1猜想
- 前端 相机 自定义取景框_索尼ZV-1数码相机:专业而易用,Vlog和网络主播的进阶良机...
- OpenLDAP的安装和配置(含TLS和复制)
- 乔布斯首份手写求职信再次被拍卖
- 华为鸿蒙麒麟玉兔_华为P50Pro概念图:1亿像素+麒麟9000+鸿蒙
- mac:文件编码问题
- Django 【第十四篇】信号
- 程序员养猫,并不是用来撸的!
- Resnet残差网络学习
- android 钛备份,钛备份使用教程
- c++ grpc 安装
- 【阿里云-如何实现实名认证】
- SNETCracker:开源的超级弱口令检查审计工具,支持批量多线程
- zblog技术导航网全站源码+数据
- 大商创 常见问题 mysql_大商创手机端出现404的官方解决方案
- 蛋白质的数据预处理个人笔记(2)
- 若非群玉山头见,会向瑶台月下逢
- Ubuntu20.04 安装ROS2 Foxy
- cordova Vue 保存视频/图片到相册 - 实现下载视频/图片到相册
热门文章
- iscsi发起程序找不到目标_3分钟学会程序员“面试回答规范”,不怕找不到工作的里面请...
- 可微偏导数一定存在_【导数压轴题】“偏导数”与含参不等式
- arcgis制作空间变化图怎么做_【教程:如何使用ArcGIS10.2制作气温空间分布图】...
- matlab中filter卷积补零,matlab中的卷积——filter,conv之间的区别
- 记录一下MATLAB中ode45函数求解非刚性微分方程
- CStopwatch详细用法
- Eclipse 3.5 Classic+Tomcat 6.0+MySql 5.5搭建java web开发环境
- HashTable已经被淘汰了,不要在代码中再使用它
- JAVA 中BIO,NIO,AIO的理解
- (转)C#开发微信门户及应用(4)--关注用户列表及详细信息管理