В чем разница между оператором new
и Class.forName(...).newInstance()
? Оба они создают экземпляры класса, и я не уверен, в чем разница между ними.
В чем разница между оператором new и Class.newInstance()?
Ответы (10)
Оператор 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()
.
- person Dávid Horváth; 14.12.2016
Class.forName("your class name").newInstance()
полезен, если вам нужно динамически создавать экземпляры классов, потому что вам не нужно жестко кодировать имя класса для создания объекта.
Представьте себе сценарий, в котором вы загружаете классы динамически из удаленного источника. Вы будете знать их имена, но не сможете импортировать их во время компиляции. В этом случае вы не можете использовать new
для создания новых экземпляров. Это (одна из причин), почему Java предлагает метод newInstance()
.
Class.forName может вызывать только конструктор по умолчанию (без параметров), а имя класса может быть предоставлено во время выполнения, например. имя db-драйвера, прочитанное из файла конфигурации.
Основное отличие состоит в том, что Class.forName('your class name').newInstance()
является динамическим, поскольку тип не нужно жестко запрограммировать в коде.
Class.forName("your class name").newInstance()
используется, когда вы хотите получить экземпляр из класса, работающего аналогично new
, но он полезен, когда вы хотите получить экземпляр из класса в jar-файле или на удаленном сервере, и вы не можете импортировать это во время компиляции.
пример: Class.forName("YOUR JDBC DRIVER").newInstance()
, вы не можете импортировать класс JDBC во время компиляции.
newInstance()
существовала только для некоторых ранних версий драйвера MySQL JDBC.
- person Mark Rotteveel; 02.10.2016
Class.forName('myClass').newInstance()
загружает класс, если он еще не загружен. Здесь он вызывает начальный конструктор и выполняет только статическую часть конструктора.
Оператор new
используется для инициализации новых объектов.
Вы можете создать много экземпляров как из оператора new
, так и из оператора Class.forName()
. Разница в том, что во второй раз, когда вы создаете статические блоки newInstance()
, они не будут инициализированы.
Хорошим примером Class.forName('myClass).newInstance()
является драйвер JDBC.
Class.forName("com.mysql.JDBC.Driver").newInstance()
newInstance()
существовала только для некоторых ранних версий драйвера MySQL JDBC.
- person Mark Rotteveel; 02.10.2016
Class.forName
выполнит поиск объекта Class
для YourClass
.
Использование нового оператора должно быть таким же, как YourClass.class.newInstance()
.
Хотя оба они фактически делают одно и то же, вы должны использовать оператор new вместо Class.forName('class').getInstance(). Последний использует API отражения для поиска класса во время выполнения. Используя новый оператор, виртуальная машина заранее узнает, что вы хотите использовать этот класс, и, следовательно, будет более эффективной.
Предположим, com.statckoverflow.Test
Class.forName
— он загрузит класс Test и вернет объект класса Class
, который содержит метаданные класса Test, такие как имя, пакет, конструктор, аннотации, методы, поля.
newInstance()
— используется для создания экземпляров новых объектов с помощью Java Reflection. В классе Test
будет вызываться конструктор с внутренним нулевым параметром. Это означает, что объект класса Class
создаст объект класса Test
, вызвав конструктор с нулевым параметром. Мы можем использовать отражение для деталей класса Test
. Как конструкторы, методы и т.д.
Оператор new
— создает новый объект для класса, создающего экземпляр Class
, и может вызывать их конструкторы.
Если у объекта нет конструктора с нулевым аргументом, он также создаст объект и не вызовет никаких исключений, пожалуйста, найдите приведенные ниже фрагменты кода.
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();
}