Class.newInstance()与new、Constructor.newInstance()的区别
【摘要】
在初始化一个类,生成一个实例的时候,newInstance() 和 new 有什么区别? 用newInstance与用new是区别的,
区别在于创建对象的方式不一样,前者是使用类加载机制,那么为什么会有两种创建对象方式?这个就要从可伸缩、可扩展,可重用等软件思想上解释了。
Java中工厂模式经常使用newInstance来...
在初始化一个类,生成一个实例的时候,newInstance() 和 new 有什么区别?
区别在于创建对象的方式不一样,前者是使用类加载机制
-
Class c = Class.forName(“A”);
-
factory = (AInterface)c.newInstance();
-
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();
从jvm的角度看,我们使用new的时候,这个要new的类可以没有加载;
但是使用newInstance时候,就必须保证:
1、这个类已经加载;
2、这个类已经连接了。
而完成上面两个步骤的正是class的静态方法forName方法,这个静态方法调用了启动类加载器(就是加载java API的那个加载器)。
newInstance实际上是把new这个方式分解为两步我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了我们降耦的手段。
只能调用无参构造
new: 强类型。相对高效。能调用任何public构造。
newInstance() 的参数版本与无参数版本详解
通过反射创建新的类示例,有两种方式:
以下对两种调用方式给以比较说明:
Class.newInstance() 只能够调用 无参的构造函数,即默认的构造函数;
Constructor.newInstance() 可以根据传入的参数,调用 任意构造构造函数。
Class.newInstance() 抛出所有由被调用构造函数抛出的异常。
Class.newInstance() 要求被调用的构造函数是可见的,也即必须是 public类型的;
Constructor.newInstance() 在特定的情况下,可以 调用私有的构造函数。
Class A(被调用的示例):
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()。
文章来源: panda1234lee.blog.csdn.net,作者:panda1234lee,版权归原作者所有,如需转载,请联系作者。
原文链接:panda1234lee.blog.csdn.net/article/details/9009719
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)