【发布时间】:2011-01-06 06:27:53
【问题描述】:
new 运算符和Class.forName(...).newInstance() 有什么区别?它们都创建了一个类的实例,我不确定它们之间有什么区别。
【问题讨论】:
-
或 Class.forName(...).getConstructor(...).newInstance(...)
标签: java reflection new-operator
new 运算符和Class.forName(...).newInstance() 有什么区别?它们都创建了一个类的实例,我不确定它们之间有什么区别。
【问题讨论】:
标签: java reflection new-operator
new 运算符创建一个静态已知类型的新对象(在编译时),并且可以在您尝试创建的对象上调用任何构造函数。这是创建对象的首选方式 - 它速度快,并且 JVM 对其进行了大量积极优化。
Class.forName().newInstance() 是一个动态构造,用于查找具有特定名称的类。它比使用new 慢,因为对象的类型不能硬编码到字节码中,并且因为JVM 可能必须进行权限检查以确保您有权创建对象。它也是部分不安全的,因为它总是使用零参数构造函数,如果您尝试创建的对象没有空值构造函数,它会引发异常。
简而言之,如果您在编译时知道要创建的对象类型是什么,请使用new。如果您不知道要制作什么类型的对象,请使用Class.forName().newInstance()。
【讨论】:
ClassNotFoundException 已选中,因此您无法编译:try { optlib.SomeClass obj = new optlib.SomeClass(); } catch (ClassNotFoundException e) {}。在这种情况下,您必须使用Class.forName().newInstance()。
Class.forName("your class name").newInstance() 在您需要动态实例化类时很有用,因为您不必硬编码类名来创建对象。
想象一个从远程源动态加载类的场景。您将知道它们的名称,但无法在编译时导入它们。在这种情况下,您不能使用 new 创建新实例。这就是 Java 提供 newInstance() 方法的(一个原因)。
【讨论】:
Class.forName 只能调用默认构造函数(不带参数)和 可以在运行时提供类名,例如从配置文件中读取的 db-driver 名称。
【讨论】:
主要区别在于Class.forName('your class name').newInstance() 是动态的,因为类型不需要硬编码到代码中。
【讨论】:
Class.forName("your class name").newInstance() 用于从类中获取实例,类似于new,但当你想从 jar 文件或远程服务器中的类中获取实例并且 无法在编译时导入它。
例如:Class.forName("YOUR JDBC DRIVER").newInstance(),您不能在编译时导入 JDBC 类。
【讨论】:
newInstance()的必要性只存在于一些早期版本的MySQL JDBC驱动中。
Class.forName('myClass').newInstance() 会加载尚未加载的类。这里它调用初始构造函数并且只执行构造函数的静态部分。
new 运算符用于初始化新对象。
您可以从new 运算符和Class.forName() 创建许多实例,区别在于您第二次创建newInstance() 静态块时不会被初始化。
Class.forName('myClass).newInstance() 的一个很好的例子是 JDBC 驱动程序
Class.forName("com.mysql.JDBC.Driver").newInstance()
【讨论】:
newInstance()的必要性只存在于一些早期版本的MySQL JDBC驱动中。
Class.forName 将查找 Class 对象以查找 YourClass。
使用new操作符应该和YourClass.class.newInstance()一样。
【讨论】:
虽然两者都有效地做同样的事情,但您应该使用 new 运算符而不是 Class.forName('class').getInstance()。后者使用反射 API 在运行时查找类。通过使用 new 运算符,VM 将事先知道您想要使用该类,从而提高效率。
【讨论】:
假设com.statckoverflow.Test
Class.forName - 它将加载 Test 类并返回 Class 类对象,其中包含 Test 类的元数据,如名称、包、构造函数、注释、方法、字段。
newInstance() - 用于使用 Java 反射实例化新对象。 Test 类将调用内部零参数构造函数。这意味着Class类对象将通过调用零参数构造函数来创建Test类对象,Test类的细节可以使用反射。比如构造函数、方法等。
new 运算符 - 为实例化 Class 的类创建新对象,并可以调用它们的构造函数。
【讨论】:
如果一个对象没有零参数构造函数,它也会创建一个对象并且不会抛出任何异常,请看下面的代码sn-ps。
try {
Class o = Class.forName("com.myCompany.MyClass");
Constructor m = o.getConstructor(Integer.class,String.class);
m.newInstance(new Integer(0),new String(""));
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
【讨论】: