web-dev-qa-db-ja.com

クラス名と呼び出しコンストラクタを使用してインスタンスを作成する

クラス名(動的)を指定して特定のクラスのインスタンスを作成し、そのコンストラクタにパラメータを渡す方法はありますか。

何かのようなもの:

Object object = createInstance("mypackage.MyClass","MyAttributeValue");

"MyAttributeValue"MyClassのコンストラクタへの引数です。

283

はい、そのようなものです。

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 {}
}

そのためのClassオブジェクトを取得するには、Class.forName("foo.Outer$Nested")が必要です。

462
Jon Skeet

Class.forName() を使用して、目的のクラスの Class オブジェクトを取得できます。

それから getConstructor() を使って目的の Constructor オブジェクトを見つけます。

最後に、そのオブジェクトに対して newInstance() を呼び出して、新しいインスタンスを取得します。

Class<?> c = Class.forName("mypackage.MyClass");
Constructor<?> cons = c.getConstructor(String.class);
Object object = cons.newInstance("MyAttributeValue");
89
Joachim Sauer

あなたは反射を使用することができます

return Class.forName(className).getConstructor(String.class).newInstance(arg);
78
Peter Lawrey

Classに空のコンストラクタが1つしかない場合(ActivityやFragmentなどのAndroidクラス)、

Class<?> myClass = Class.forName("com.example.MyClass");    
Constructor<?> constructor = myClass.getConstructors()[0];
12
tier777

(すなわち)getConstructor(String.lang)を使用するとき、コンストラクタはpublicとして宣言されなければなりません。そうでなければNoSuchMethodExceptionが投げられます。

非公開コンストラクタにアクセスしたい場合 代わりにgetDeclaredConstructor(String.lang)を使用する必要があります。

8
4
Alan Escreet

コンストラクタ引数を渡してClass<?>を使用してJavaでオブジェクトを作成するための非常に簡単な方法:

ケース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: - /あなたは、複数の引数を持つコンストラクタとコピーコンストラクタのために同様にコーディングすることができます。たとえば、Baseコンストラクタにパラメータとして3つの引数を渡すには、コンストラクタをクラス内で作成し、上記のようにコードを変更する必要があります。

Constructor<?> ctr = myClass.getConstructor(String.class, String.class, String.class);
Object object = ctr.newInstance(new Object[] { "Arg1", "Arg2", "Arg3" }); 

そしてここでBaseクラスはどういうわけか次のようになるはずです。

public class Base {

    public Base(String a, String b, String c){
        // This constructor need to be created in this case.
    }   
}

注: - コード内で処理する必要があるさまざまな例外を処理することを忘れないでください。

3
Rahul Raina

シングルトンパターンに従うクラスにもかかわらず、誰かがクラスのインスタンスを作成する方法を探しているなら、ここにそれをする方法があります。

// 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();

これはプライベートコンストラクタを使用してシングルトンパターンを実装するクラスに対してのみ機能します。

1
Omer

作成したオブジェクト内でメソッドを呼び出すこともできます。

最初のコンストラクタを呼び出してから、作成したオブジェクトの最初のメソッドを呼び出すことで、オブジェクトを即座に作成できます。

    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);
1
Hatem Badawi

もう一つの役に立つ答え。 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);
0
user3181500