มีวิธีสร้างอินสแตนซ์ของคลาสเฉพาะที่กำหนดชื่อคลาส (ไดนามิก) และส่งพารามิเตอร์ไปยังตัวสร้างหรือไม่
สิ่งที่ต้องการ:
Object object = createInstance("mypackage.MyClass","MyAttributeValue");
ที่ไหนเป็นอาร์กิวเมนต์คอนสตรัคของ"MyAttributeValue"MyClass
มีวิธีสร้างอินสแตนซ์ของคลาสเฉพาะที่กำหนดชื่อคลาส (ไดนามิก) และส่งพารามิเตอร์ไปยังตัวสร้างหรือไม่
สิ่งที่ต้องการ:
Object object = createInstance("mypackage.MyClass","MyAttributeValue");
ที่ไหนเป็นอาร์กิวเมนต์คอนสตรัคของ"MyAttributeValue"MyClass
คำตอบ:
ใช่บางสิ่งเช่น:
Class<?> clazz = Class.forName(className);
Constructor<?> ctor = clazz.getConstructor(String.class);
Object object = ctor.newInstance(new Object[] { ctorArgument });
แน่นอนว่าจะใช้ได้กับพารามิเตอร์สตริงเดียวเท่านั้น แต่คุณสามารถแก้ไขได้อย่างง่ายดาย
โปรดทราบว่าชื่อคลาสจะต้องเป็นชื่อที่ผ่านการรับรองเช่นรวมถึงเนมสเปซ สำหรับคลาสที่ซ้อนกันคุณจำเป็นต้องใช้เงินดอลลาร์ (นั่นคือสิ่งที่คอมไพเลอร์ใช้) ตัวอย่างเช่น:
package foo;
public class Outer
{
public static class Nested {}
}
ที่จะได้รับวัตถุสำหรับการที่คุณจะต้องClassClass.forName("foo.Outer$Nested")
Object[]ข้อโต้แย้งฉันสามารถสร้างอาร์เรย์ได้อย่างชัดเจนในกรณีนี้
คุณสามารถใช้Class.forName()เพื่อรับClassวัตถุของคลาสที่ต้องการ
จากนั้นใช้getConstructor()เพื่อค้นหาสิ่งที่ต้องการConstructorวัตถุ
สุดท้ายให้โทรหาnewInstance()วัตถุนั้นเพื่อรับอินสแตนซ์ใหม่ของคุณ
Class<?> c = Class.forName("mypackage.MyClass");
Constructor<?> cons = c.getConstructor(String.class);
Object object = cons.newInstance("MyAttributeValue");
คุณสามารถใช้การสะท้อน
return Class.forName(className).getConstructor(String.class).newInstance(arg);
Class.forName(className).getConstructor().newInstance();;)
ถ้า class มี Constructor ว่างเปล่าเพียงอันเดียว (เช่น Activity หรือ Fragment เป็นต้น, คลาส Android):
Class<?> myClass = Class.forName("com.example.MyClass");
Constructor<?> constructor = myClass.getConstructors()[0];
Constructor<?> ctor = clazz.getConstructor(String.class)ดูเหมือนจะไม่ได้ผลสำหรับฉัน
เมื่อใช้ (เช่น) getConstructor(String.lang)ตัวสร้างจะต้องประกาศสู่สาธารณะ มิฉะนั้นNoSuchMethodExceptionจะถูกโยน
ถ้าคุณต้องการที่จะเข้าถึงตัวสร้างที่ไม่ใช่แบบสาธารณะคุณมีที่จะใช้แทน getDeclaredConstructor(String.lang)(IE)
คุณต้องการที่จะใช้java.lang.reflect.Constructor.newInstance (Object ... )
วิธีที่ง่ายมากในการสร้างวัตถุใน Java โดยใช้การClass<?>ส่งผ่านอาร์กิวเมนต์ตัวสร้าง:
กรณีที่ 1: -
นี่คือรหัสขนาดเล็กในMainชั้นนี้:
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Main {
public static void main(String args[]) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// Get class name as string.
String myClassName = Base.class.getName();
// Create class of type Base.
Class<?> myClass = Class.forName(myClassName);
// Create constructor call with argument types.
Constructor<?> ctr = myClass.getConstructor(String.class);
// Finally create object of type Base and pass data to constructor.
String arg1 = "My User Data";
Object object = ctr.newInstance(new Object[] { arg1 });
// Type-cast and access the data from class Base.
Base base = (Base)object;
System.out.println(base.data);
}
}
และนี่คือBaseโครงสร้างคลาส:
public class Base {
public String data = null;
public Base()
{
data = "default";
System.out.println("Base()");
}
public Base(String arg1) {
data = arg1;
System.out.println("Base("+arg1+")");
}
}
กรณีที่ 2: -คุณสามารถโค้ดในทำนองเดียวกันสำหรับคอนสตรัคเตอร์ที่มีอาร์กิวเมนต์หลายตัวและคัดลอกคอนสตรัคเตอร์ ตัวอย่างเช่นการส่งอาร์กิวเมนต์ 3 ตัวเป็นพารามิเตอร์ให้กับตัวBaseสร้างจะต้องใช้ตัวสร้างเพื่อสร้างในคลาสและการเปลี่ยนรหัสในด้านบนเป็น:
Constructor<?> ctr = myClass.getConstructor(String.class, String.class, String.class);
Object object = ctr.newInstance(new Object[] { "Arg1", "Arg2", "Arg3" });
และที่นี่ชั้นฐานควรมีลักษณะอย่างไร:
public class Base {
public Base(String a, String b, String c){
// This constructor need to be created in this case.
}
}
หมายเหตุ: - อย่าลืมจัดการข้อยกเว้นต่าง ๆ ซึ่งจำเป็นต้องจัดการในรหัส
หากใครกำลังมองหาวิธีในการสร้างตัวอย่างของชั้นเรียนแม้จะมีชั้นเรียนตามรูปแบบ Singleton นี่คือวิธีที่จะทำ
// Get Class instance
Class<?> clazz = Class.forName("myPackage.MyClass");
// Get the private constructor.
Constructor<?> cons = clazz.getDeclaredConstructor();
// Since it is private, make it accessible.
cons.setAccessible(true);
// Create new object.
Object obj = cons.newInstance();
ใช้งานได้กับคลาสที่ใช้รูปแบบซิงเกิลโดยใช้ Constructor ส่วนตัวเท่านั้น
นอกจากนี้คุณยังสามารถเรียกใช้วิธีการภายในวัตถุที่สร้างขึ้น
คุณสามารถสร้างออบเจกต์ได้ทันทีโดยเรียกใช้ constractor แรกจากนั้นเรียกใช้เมธอดแรกในวัตถุที่สร้างขึ้น
Class<?> c = Class.forName("mypackage.MyClass");
Constructor<?> ctor = c.getConstructors()[0];
Object object=ctor.newInstance(new Object[]{"ContstractorArgs"});
c.getDeclaredMethods()[0].invoke(object,Object... MethodArgs);
Stringเป็นพารามิเตอร์ จะยุ่งเล็กน้อยเมื่อคุณเปลี่ยนคำสั่งคอนสตรัคเตอร์
getConstructor(ClassName.class)ดีกว่าฉันเดา แม้ว่าคำสั่งของผู้สร้างเปลี่ยนแปลงในชั้นเรียนไม่จำเป็นต้องค้นหาตำแหน่งด้วยตนเอง
อีกคำตอบที่เป็นประโยชน์ ฉันจะใช้ getConstructor (params) .newInstance (args) ได้อย่างไร
return Class.forName(**complete classname**)
.getConstructor(**here pass parameters passed in constructor**)
.newInstance(**here pass arguments**);
ในกรณีของฉันตัวสร้างคลาสของฉันใช้ Webdriver เป็นพารามิเตอร์ดังนั้นใช้โค้ดด้านล่าง:
return Class.forName("com.page.BillablePage")
.getConstructor(WebDriver.class)
.newInstance(this.driver);
newInstance()เป็นวิธีการ varargs (เช่นเดียวกับGetConstructor()) ไม่จำเป็นต้องมีObjectการสร้าง -array อย่างชัดเจน