В чем разница между оператором new и Class.newInstance()?

В чем разница между оператором new и Class.forName(...).newInstance()? Оба они создают экземпляры класса, и я не уверен, в чем разница между ними.


person i2ijeya    schedule 06.01.2011    source источник
comment
или Class.forName(...).getConstructor(...).newInstance(...)   -  person viavad    schedule 10.06.2019


Ответы (10)


Оператор new создает новый объект типа, который известен статически (во время компиляции) и может вызывать любой конструктор объекта, который вы пытаетесь создать. Это предпочтительный способ создания объекта — он быстрый, и JVM выполняет множество агрессивных оптимизаций.

Class.forName().newInstance() — это динамическая конструкция, которая ищет класс с определенным именем. Это медленнее, чем использование new, поскольку тип объекта не может быть жестко запрограммирован в байт-коде, а также потому, что JVM может потребоваться выполнить проверку разрешений, чтобы убедиться, что у вас есть полномочия для создания объекта. Это также частично небезопасно, поскольку всегда использует конструктор с нулевым аргументом, и если объект, который вы пытаетесь создать, не имеет конструктора с нулевым аргументом, он выдает исключение.

Короче говоря, используйте new, если во время компиляции вы знаете, какой тип объекта вы хотите создать. Используйте Class.forName().newInstance(), если вы не знаете, какой тип объекта вы будете делать.

person templatetypedef    schedule 06.01.2011
comment
Это популярный вопрос на собеседовании, и это отличный ответ... спасибо - person Soumyadip Das; 06.08.2012
comment
вы можете получить конструкторы, которым требуются аргументы, и использовать их для создания экземпляра объекта через API отражения. - person Manjunath Maruthi; 08.01.2015
comment
Просто примечание, ClassNotFoundException проверено, поэтому вы не можете скомпилировать это: try { optlib.SomeClass obj = new optlib.SomeClass(); } catch (ClassNotFoundException e) {}. В этом случае вы должны использовать Class.forName().newInstance(). - person Dávid Horváth; 14.12.2016
comment
безупречный ответ! - person Gaurav; 17.10.2019

Class.forName("your class name").newInstance() полезен, если вам нужно динамически создавать экземпляры классов, потому что вам не нужно жестко кодировать имя класса для создания объекта.

Представьте себе сценарий, в котором вы загружаете классы динамически из удаленного источника. Вы будете знать их имена, но не сможете импортировать их во время компиляции. В этом случае вы не можете использовать new для создания новых экземпляров. Это (одна из причин), почему Java предлагает метод newInstance().

person Andreas Dolk    schedule 06.01.2011
comment
Большой!! Это полезный ответ!! - person Emad Aghayi; 30.12.2015

Class.forName может вызывать только конструктор по умолчанию (без параметров), а имя класса может быть предоставлено во время выполнения, например. имя db-драйвера, прочитанное из файла конфигурации.

person stacker    schedule 06.01.2011
comment
Это неверно, вы можете получить конструкторы, которым требуются аргументы, и использовать их для создания экземпляра объекта через API отражения. Однако метод newInstance специально вызывает конструктор без аргументов и требует, чтобы он был видимым и доступным. Ответ templatetypedef является наиболее полным/правильным и информативным. - person LINEMAN78; 06.01.2011

Основное отличие состоит в том, что Class.forName('your class name').newInstance() является динамическим, поскольку тип не нужно жестко запрограммировать в коде.

person fastcodejava    schedule 10.05.2013

Class.forName("your class name").newInstance() используется, когда вы хотите получить экземпляр из класса, работающего аналогично new, но он полезен, когда вы хотите получить экземпляр из класса в jar-файле или на удаленном сервере, и вы не можете импортировать это во время компиляции.

пример: Class.forName("YOUR JDBC DRIVER").newInstance(), вы не можете импортировать класс JDBC во время компиляции.

person Emad Aghayi    schedule 30.12.2015
comment
Пример 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()
person Nipuna    schedule 06.01.2011
comment
Что, если я использую Class‹myClass› inst1 = (Class‹myClass›)Class.forName('myClass).getInstance()...... Class‹myClass› inst2 = (Class‹myClass›)Class.forName(' myClass).getInstance()............... Это сделает несколько экземпляров правильными. - person i2ijeya; 06.01.2011
comment
Ну, я не нахожу метод getInstance(). Ты? - person Nipuna; 06.01.2011
comment
Пример JDBC на самом деле не очень хорош, необходимость вызывать newInstance() существовала только для некоторых ранних версий драйвера MySQL JDBC. - person Mark Rotteveel; 02.10.2016

Class.forName выполнит поиск объекта Class для YourClass.

Использование нового оператора должно быть таким же, как YourClass.class.newInstance().

person Zeki    schedule 06.01.2011

Хотя оба они фактически делают одно и то же, вы должны использовать оператор new вместо Class.forName('class').getInstance(). Последний использует API отражения для поиска класса во время выполнения. Используя новый оператор, виртуальная машина заранее узнает, что вы хотите использовать этот класс, и, следовательно, будет более эффективной.

person salexander    schedule 06.01.2011

Предположим, com.statckoverflow.Test

Class.forName — он загрузит класс Test и вернет объект класса Class, который содержит метаданные класса Test, такие как имя, пакет, конструктор, аннотации, методы, поля.

newInstance() — используется для создания экземпляров новых объектов с помощью Java Reflection. В классе Test будет вызываться конструктор с внутренним нулевым параметром. Это означает, что объект класса Class создаст объект класса Test, вызвав конструктор с нулевым параметром. Мы можем использовать отражение для деталей класса Test. Как конструкторы, методы и т.д.

Оператор new — создает новый объект для класса, создающего экземпляр Class, и может вызывать их конструкторы.

person Kanchan Kumar    schedule 13.10.2017

Если у объекта нет конструктора с нулевым аргументом, он также создаст объект и не вызовет никаких исключений, пожалуйста, найдите приведенные ниже фрагменты кода.

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();
}
person user2364795    schedule 09.05.2013