Apa perbedaan antara Class.forName()
dan Class.forName().newInstance()
?
Saya tidak mengerti perbedaan yang signifikan (saya telah membaca sesuatu tentang mereka!). Bisakah bantu saya?
Mungkin contoh yang menunjukkan bagaimana kedua metode digunakan akan membantu Anda untuk memahami hal-hal dengan lebih baik. Jadi, pertimbangkan kelas berikut:
package test;
public class Demo {
public Demo() {
System.out.println("Hi!");
}
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("test.Demo");
Demo demo = (Demo) clazz.newInstance();
}
}
Seperti dijelaskan dalam javadoc-nya, panggilan mengembalikan objek yang terkait dengan kelas atau antarmuka dengan nama string yang diberikan yaitu mengembalikan yang dipengaruhi oleh variabel tipe .Class.forName(String)
Class
test.Demo.class
clazz
Class
Kemudian, panggilan menciptakan instance baru dari kelas yang diwakili oleh objek ini . Kelas dipakai sebagai seolah-olah oleh ekspresi dengan daftar argumen kosong. Dengan kata lain, ini di sini sebenarnya setara dengan dan mengembalikan instance baru .clazz.newInstance()
Class
new
new Demo()
Demo
Dan menjalankan Demo
kelas ini dengan demikian mencetak output berikut:
Hi!
Perbedaan besar dengan tradisional new
adalah yang newInstance
memungkinkan untuk instantiate kelas yang Anda tidak tahu sampai runtime, membuat kode Anda lebih dinamis.
Contoh tipikal adalah JDBC API yang memuat, saat runtime, driver yang dibutuhkan untuk melakukan pekerjaan. Wadah EJB, wadah Servlet adalah contoh bagus lainnya: mereka menggunakan pemuatan runtime dinamis untuk memuat dan membuat komponen yang tidak mereka ketahui sebelum runtime.
Sebenarnya, jika Anda ingin melangkah lebih jauh, lihatlah makalah Ted Neward Understanding Class.forName () yang saya kutip dalam paragraf di atas.
EDIT (menjawab pertanyaan dari OP yang diposting sebagai komentar): Kasus driver JDBC agak istimewa. Seperti yang dijelaskan dalam bab DriverManager tentang Memulai dengan JDBC API :
(...)
Driver
Kelas dimuat, dan karenanya secara otomatis terdaftar denganDriverManager
, dalam salah satu dari dua cara:
dengan memanggil metode
Class.forName
. Ini secara eksplisit memuat kelas driver. Karena tidak tergantung pada pengaturan eksternal apa pun, cara memuat driver ini adalah yang disarankan untuk menggunakanDriverManager
kerangka kerja. Kode berikut memuat kelasacme.db.Driver
:Class.forName("acme.db.Driver");
Jika
acme.db.Driver
telah ditulis sehingga memuatnya menyebabkan instance dibuat dan juga memanggilDriverManager.registerDriver
instance tersebut sebagai parameter (seperti yang seharusnya), maka itu ada dalamDriverManager
daftar driver dan tersedia untuk membuat koneksi.(...)
Dalam kedua kasus ini, adalah tanggung jawab kelas yang baru dimuat
Driver
untuk mendaftar sendiri dengan meneleponDriverManager.registerDriver
. Seperti disebutkan, ini harus dilakukan secara otomatis ketika kelas dimuat.
Untuk mendaftar sendiri selama inisialisasi, driver JDBC biasanya menggunakan blok inisialisasi statis seperti ini:
package acme.db;
public class Driver {
static {
java.sql.DriverManager.registerDriver(new Driver());
}
...
}
Panggilan Class.forName("acme.db.Driver")
menyebabkan inisialisasi acme.db.Driver
kelas dan dengan demikian eksekusi blok inisialisasi statis. Dan Class.forName("acme.db.Driver")
memang akan "membuat" contoh tetapi ini hanya konsekuensi dari bagaimana (baik) Driver JDBC diimplementasikan.
Sebagai catatan, saya akan menyebutkan bahwa semua ini tidak diperlukan lagi dengan JDBC 4.0 (ditambahkan sebagai paket default sejak Java 7) dan fitur auto-loading baru dari driver JDBC 4.0. Lihat peningkatan JDBC 4.0 di Java SE 6 .
DriverManager.registerDriver
. MemanggilClass.forName
driver JDBC menyebabkan inisialisasi dan dengan demikian eksekusi blok statis. Lihat java2s.com/Open-Source/Java-Document/Database-DBMS/… untuk contoh. Jadi ini sebenarnya adalah kasus khusus karena pengemudi internal.Class.forName () memberi Anda objek kelas, yang berguna untuk refleksi. Metode yang dimiliki objek ini ditentukan oleh Java, bukan oleh programmer yang menulis kelas. Mereka sama untuk setiap kelas. Memanggil newInstance () pada yang memberikan Anda sebuah instance dari kelas itu (yaitu memanggil
Class.forName("ExampleClass").newInstance()
itu setara dengan memanggilnew ExampleClass()
), di mana Anda dapat memanggil metode yang didefinisikan oleh kelas, mengakses bidang yang terlihat dll.sumber
Di dunia JDBC, praktik normal (menurut JDBC API) adalah yang Anda gunakan
Class#forName()
untuk memuat driver JDBC. Driver JDBC harus mendaftar diDriverManager
dalam blok statis:Memohon
Class#forName()
akan menjalankan semua inisialisasi statis . Dengan cara iniDriverManager
dapat menemukan driver terkait di antara driver terdaftar dengan URL koneksi digetConnection()
mana kira-kira terlihat seperti berikut:Tapi ada juga kereta driver JDBC, dimulai dengan
org.gjt.mm.mysql.Driver
contoh juga dikenal, yang tidak benar mendaftarkan diri dalam Constructor bukan blok statis:Satu-satunya cara untuk membuatnya bekerja secara dinamis adalah menelepon
newInstance()
sesudahnya! Kalau tidak, Anda akan menghadapi pandangan pertama yang tidak dapat dijelaskan "SQLException: no driver yang sesuai". Sekali lagi, ini adalah bug pada driver JDBC, bukan di kode Anda sendiri. Saat ini, tidak ada driver JDBC yang boleh mengandung bug ini. Jadi Anda dapat (dan harus) meninggalkan tempatnewInstance()
itu.sumber
1: jika Anda hanya tertarik pada blok statis kelas, pemuatan kelas hanya akan dilakukan, dan akan menjalankan blok statis maka yang Anda butuhkan adalah:
2: jika Anda tertarik untuk memuat kelas, jalankan blok-blok statisnya dan juga ingin mengakses bagian non-statisnya, maka Anda memerlukan sebuah instance dan kemudian Anda perlu:
sumber
Class.forName () mendapatkan referensi ke Class, Class.forName (). NewInstance () mencoba menggunakan konstruktor no-arg untuk Kelas untuk mengembalikan instance baru.
sumber
"Class.forName ()" mengembalikan Tipe-Kelas untuk nama yang diberikan. "newInstance ()" mengembalikan instance kelas ini.
Pada tipe yang Anda tidak dapat memanggil langsung metode instance tetapi hanya dapat menggunakan refleksi untuk kelas. Jika Anda ingin bekerja dengan objek kelas Anda harus membuat turunannya (sama dengan memanggil "MyClass baru ()").
Contoh untuk "Class.forName ()"
Contoh untuk "Class.forName (). NewInstance ()"
sumber
hanya menambahkan jawaban di atas, ketika kita memiliki kode statis (mis. blok kode adalah contoh independen) yang perlu ada dalam memori, kita dapat meminta kelas dikembalikan sehingga kita akan menggunakan Class.forname ("someName") yang lain jika kita jangan punya kode statis, kita bisa menggunakan Class.forname (). newInstance ("someName") karena akan memuat blok kode level objek (non statis) ke memori
sumber
Tidak peduli berapa kali Anda memanggil metode Class.forName (), Hanya sekali blok statis dijalankan tidak beberapa kali:
MainClass kelas publik {
}
DemoClass kelas publik {
}
output akan menjadi:
in Static block in Instance block
Ini
in Static block
Pernyataan dicetak hanya sekali bukan tiga kali.sumber
Class.forName () -> forName () adalah metode statis kelas Kelas yang dikembalikannya objek kelas Kelas yang digunakan untuk refleksi bukan objek kelas pengguna sehingga Anda hanya dapat memanggil metode kelas Kelas di atasnya seperti getMethods (), getConstructors () dll.
Jika Anda peduli hanya menjalankan blok statis dari kelas Anda (diberikan Runtime) dan hanya mendapatkan informasi tentang metode, konstruktor, Modifier dll dari kelas Anda, Anda dapat melakukannya dengan objek ini yang Anda dapatkan menggunakan Class.forName ()
Tetapi jika Anda ingin mengakses atau memanggil metode kelas Anda (kelas yang telah Anda berikan saat runtime) maka Anda perlu memiliki objeknya sehingga metode Kelas baru melakukannya untuk Anda. Ini membuat instance baru dari kelas dan mengembalikannya kepada Anda Anda hanya perlu mengetikkan gips ke kelas Anda.
mis.: anggaplah Karyawan adalah kelas Anda saat itu
Class a = Class.forName (args [0]);
// args [0] = argumen garis cmd untuk memberikan kelas saat runtime.
Karyawan ob1 = a.newInstance ();
a.newInstance () mirip dengan membuat objek menggunakan Karyawan baru ().
sekarang Anda dapat mengakses semua bidang dan metode yang terlihat kelas Anda.
sumber