Каква е разликата между оператора new
и Class.forName(...).newInstance()
? И двамата създават екземпляри на клас и не съм сигурен каква е разликата между тях.
Каква е разликата между новия оператор и 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 за отражение, за да търси класа по време на изпълнение. Чрез използването на новия оператор VM ще знае предварително, че искате да използвате този клас и по този начин да бъдете по-ефективни.
Да приемем com.statckoverflow.Test
Class.forName
- Ще зареди тестовия клас и ще върне обекта на Class
клас, който съдържа метаданните на тестовия клас като име, пакет, конструктор, анотации, методи, полета.
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();
}