ฉันกำลังมองหาคำถาม: สร้างอินสแตนซ์คลาสจากชื่อสตริงซึ่งอธิบายถึงวิธีการสร้างอินสแตนซ์คลาสเมื่อมีชื่อ มีวิธีทำใน Java ไหม? ฉันจะมีชื่อแพ็กเกจและชื่อคลาสและฉันต้องสามารถสร้างอ็อบเจกต์ที่มีชื่อเฉพาะนั้นได้
ฉันกำลังมองหาคำถาม: สร้างอินสแตนซ์คลาสจากชื่อสตริงซึ่งอธิบายถึงวิธีการสร้างอินสแตนซ์คลาสเมื่อมีชื่อ มีวิธีทำใน Java ไหม? ฉันจะมีชื่อแพ็กเกจและชื่อคลาสและฉันต้องสามารถสร้างอ็อบเจกต์ที่มีชื่อเฉพาะนั้นได้
คำตอบ:
สองทาง:
หากคลาสของคุณมีตัวสร้างที่ไม่มีอาร์กิวเมนต์คุณจะได้รับClass
วัตถุโดยใช้Class.forName()
และใช้newInstance()
วิธีการสร้างอินสแตนซ์ (แต่โปรดระวังว่าวิธีนี้มักถูกมองว่าชั่วร้ายเพราะสามารถเอาชนะข้อยกเว้นที่ตรวจสอบของ Java ได้)
ตัวอย่างเช่น:
Class<?> clazz = Class.forName("java.util.Date");
Object date = clazz.newInstance();
วิธีอื่นที่ปลอดภัยกว่าซึ่งใช้ได้ผลเช่นกันหากคลาสไม่มีตัวสร้างที่ไม่มีอาร์กิวเมนต์คือการสอบถามคลาสของคุณเพื่อรับConstructor
อ็อบเจ็กต์และเรียกnewInstance()
เมธอดบนอ็อบเจ็กต์นี้:
Class<?> clazz = Class.forName("com.foo.MyClass");
Constructor<?> constructor = clazz.getConstructor(String.class, Integer.class);
Object instance = constructor.newInstance("stringparam", 42);
ทั้งสองวิธีนี้เรียกว่าการสะท้อน โดยทั่วไปคุณจะต้องตรวจสอบข้อยกเว้นต่างๆที่อาจเกิดขึ้นรวมถึงสิ่งต่างๆเช่น:
newInstance()
แล้วเราจะโยนมันกลับไปที่วัตถุของเราเองได้ไหม
instance
ไปได้com.foo.MyClass
อย่างไร? เนื่องจากcom.foo.MyClassเป็นเพียงสตริง
MyClass myInstance = (MyClass) Class.forName("MyClass").newInstance();
ใช้Class.forName ("ชื่อสตริงของคลาส") newInstance ();
Class.forName("A").newInstance();
สิ่งนี้จะทำให้คลาสชื่อ A เริ่มต้น
เพื่อให้ง่ายต่อการรับชื่อแบบเต็มของคลาสเพื่อสร้างอินสแตนซ์โดยใช้Class.forName(...)
เราสามารถใช้Class.getName()
เมธอด สิ่งที่ต้องการ:
class ObjectMaker {
// Constructor, fields, initialization, etc...
public Object makeObject(Class<?> clazz) {
Object o = null;
try {
o = Class.forName(clazz.getName()).newInstance();
} catch (ClassNotFoundException e) {
// There may be other exceptions to throw here,
// but I'm writing this from memory.
e.printStackTrace();
}
return o;
}
}
จากนั้นคุณสามารถโยนวัตถุที่คุณกลับไปยังคลาสใดก็ได้ที่คุณผ่านไปmakeObject(...)
:
Data d = (Data) objectMaker.makeObject(Data.class);
clazz.newInstance()
แทนgetName
แล้วfromName
?
ใช้การสะท้อน java
การสร้างอ็อบเจ็กต์ใหม่ไม่มีวิธีใดเทียบเท่ากับการเรียกใช้เมธอดสำหรับคอนสตรัคเตอร์เนื่องจากการเรียกใช้คอนสตรัคเตอร์เทียบเท่ากับการสร้างอ็อบเจ็กต์ใหม่ (เพื่อให้แม่นยำที่สุดการสร้างอ็อบเจ็กต์ใหม่เกี่ยวข้องกับการจัดสรรหน่วยความจำและการสร้างอ็อบเจ็กต์) ดังนั้นสิ่งที่ใกล้เคียงที่สุดกับตัวอย่างก่อนหน้านี้คือการพูดว่า:
import java.lang.reflect.*;
public class constructor2 {
public constructor2()
{
}
public constructor2(int a, int b)
{
System.out.println(
"a = " + a + " b = " + b);
}
public static void main(String args[])
{
try {
Class cls = Class.forName("constructor2");
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
Constructor ct
= cls.getConstructor(partypes);
Object arglist[] = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
Object retobj = ct.newInstance(arglist);
}
catch (Throwable e) {
System.err.println(e);
}
}
}
ซึ่งค้นหาตัวสร้างที่จัดการกับชนิดพารามิเตอร์ที่ระบุและเรียกใช้เพื่อสร้างอินสแตนซ์ใหม่ของอ็อบเจ็กต์ คุณค่าของแนวทางนี้คือเป็นแบบไดนามิกโดยมีการค้นหาตัวสร้างและการเรียกใช้ ณ เวลาดำเนินการแทนที่จะเป็นเวลาคอมไพล์
Class.forName ("ClassName")จะแก้จุดประสงค์ของคุณ
Class class1 = Class.forName(ClassName);
Object object1 = class1.newInstance();
String str = (String)Class.forName("java.lang.String").newInstance();
อะไรแบบนี้น่าจะใช้ได้ ...
String name = "Test2";//Name of the class
Class myClass = Class.forName(name);
Object o = myClass.newInstance();
การใช้newInstance()
โดยตรงจะเลิกใช้งานใน Java 8 คุณจำเป็นต้องใช้Class.getDeclaredConstructor(...).newInstance(...)
กับข้อยกเว้นที่เกี่ยวข้อง