先日、これについて同僚と会話しました。
明らかなコンストラクタの使い方がありますが、他の方法は何ですか?
Javaでオブジェクトを作成する方法は4つあります。
A。 new
キーワードを使用する
これは、Javaでオブジェクトを作成するための最も一般的な方法です。このようにして、ほぼ99%のオブジェクトが作成されます。
MyObject object = new MyObject();
B。 Class.forName()
を使う
クラスの名前がわかっていて、それにパブリックのデフォルトコンストラクタがある場合は、この方法でオブジェクトを作成できます。
MyObject object = (MyObject) Class.forName("subin.rnd.MyObject").newInstance();
C。 clone()
を使う
clone()を使って既存のオブジェクトのコピーを作成することができます。
MyObject anotherObject = new MyObject();
MyObject object = (MyObject) anotherObject.clone();
D。 object deserialization
を使う
オブジェクトの逆シリアル化は、直列化された形式からオブジェクトを作成することに他なりません。
ObjectInputStream inStream = new ObjectInputStream(anInputStream );
MyObject object = (MyObject) inStream.readObject();
こちら から読むことができます。
さまざまな方法があります。
Class.newInstance
を通じて。Constructor.newInstance
を通じて。Object.clone
を通して(コンストラクターを呼び出さない)。new
を呼び出す他のメソッドを通して。String
sなど)。...
)メソッド呼び出し内の配列(配列用のコンストラクタはありません)。throw null;
や"".toCharArray()[0]
です。new
キーワードを使った構文もあります。Java言語の中では、オブジェクトを作成する唯一の方法は、そのコンストラクターを呼び出すことです(明示的または暗黙的)。リフレクションを使用してコンストラクタメソッドを呼び出すと、デシリアライゼーションはリフレクションを使用してコンストラクタを呼び出します。ファクトリメソッドはコンストラクタへの呼び出しをラップして実際のコンストラクションを抽象化し、クローン作成も同様にラップされたコンストラクタコールです。
はい、反射を使ってオブジェクトを作成できます。例えばString.class.newInstance()
はあなたに新しい空のStringオブジェクトを与えます。
Javaでオブジェクトを作成する方法は5つあります。
1。 new
name__キーワードを使用する→コンストラクタが呼び出される
Employee emp1 = new Employee();
2。 Class
nameのnewInstance()
メソッドを使う__→コンストラクタが呼ばれる
Employee emp2 = (Employee) Class.forName("org.programming.mitra.exercises.Employee")
.newInstance();
次のように書くこともできます。
Employee emp2 = Employee.class.newInstance();
3。 Constructor
nameのnewInstance()
メソッドを使う__→コンストラクタが呼ばれる
Constructor<Employee> constructor = Employee.class.getConstructor();
Employee emp3 = constructor.newInstance();
4。 clone()
メソッドを使用する→コンストラクタを呼び出さない
Employee emp4 = (Employee) emp3.clone();
5。逆シリアル化を使用する→コンストラクタ呼び出しなし
ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
Employee emp5 = (Employee) in.readObject();
最初の3つのメソッドnew
name__キーワードと両方のnewInstance()
はコンストラクター呼び出しを含みますが、後の2つのcloneメソッドと逆シリアル化メソッドはコンストラクターを呼び出さずにオブジェクトを作成します。
上記のすべてのメソッドには、それぞれ異なるバイトコードが関連付けられています。Read 例および/詳細な説明については、例 を使用してJavaでオブジェクトを作成する方法は異なります。これらすべてのメソッドのバイトコード変換.
しかし、配列または文字列オブジェクトを作成することもオブジェクトを作成する方法であると主張できますが、これらのことはクラスによってのみ特定され、JVMによって直接処理されます。
通常のインスタンス作成メカニズム(コンストラクタを呼び出す)では構築できないオブジェクトの種類があります。配列。配列はで作成されます
A[] array = new A[len];
または
A[] array = new A[] { value0, value1, value2 };
Seanがコメントで述べたように、これは構文的にはコンストラクタ呼び出しと似ており、内部的には割り当てとゼロ初期化(または明示的な内容で初期化すること、後者の場合)を意味します。種類と長さ。
引数をvarargsメソッドに渡すと、配列も暗黙のうちに作成され(そして埋められ)ます。
4番目の方法は
A[] array = (A[]) Array.newInstance(A.class, len);
もちろん、クローン作成と逆シリアル化もここで機能します。
標準APIには配列を作成するメソッドがたくさんありますが、実際にはこれらのメソッドのうちの1つ(または複数)を使用しています。
また使用することができます
Object myObj = Class.forName("your.cClass").newInstance();
あなたがJavaに不慣れであるならば、これは注意されるべきです、すべてのオブジェクトはObjectから継承しました
保護されたネイティブのObject clone()はCloneNotSupportedExceptionをスローします。
また、データをオブジェクトにデシリアライズすることもできます。これはコンストラクタクラスを通らない!
UPDATED:あなたのコメントでそれを指摘してくれてありがとうTomそしてマイケルも実験した。
最も派生しているシリアライズ不可能なスーパークラスのコンストラクタを通過します。
そして、そのクラスに引数のないコンストラクタがない場合、直列化復元時にInvalidClassExceptionがスローされます。
トムの答えを見て、すべてのケースを完全に処理してください;-)
Javaで "new"キーワードを使わずにオブジェクトを作成する方法は他にもあります
私たちが徹底的であるならば他の方法。
anewarray
、multianewarray
、newarray
、またはnew
にコードを追加できます。これらは、ASMやBCELなどのライブラリを使用して追加できます。あるバージョンのbcelがOracleのJavaに同梱されています。これもコンストラクタを呼び出しませんが、コンストラクタを別々の呼び出しとして呼び出すことができます。反射もあなたのために仕事をするでしょう。
SomeClass anObj = SomeClass.class.newInstance();
クラスの新しいインスタンスを作成する別の方法です。この場合は、スローされる可能性のある例外も処理する必要があります。
new
演算子を使用する(したがってコンストラクタを呼び出す)clazz.newInstance()
を使用します(これもコンストラクタを呼び出します)。あるいはclazz.getConstructor(..).newInstance(..)
によって(やはりコンストラクタを使用しますが、あなたはどちらを選択することができます)オブジェクトクラスのコンストラクタを呼び出すことで、答えを要約することができます。これは主な方法の1つです。
更新:別の回答では、コンストラクタを使用しない2つの方法がリストされています。
反射:
someClass.newInstance();
既存のオブジェクトのクローンを作成することもできます(それがクローン可能を実装している場合)。
Foo fooClone = fooOriginal.clone ();
Javaでオブジェクトを作成する方法は5つあります。
これは、Javaでオブジェクトを作成するための最も一般的な方法です。このようにして、ほぼ99%のオブジェクトが作成されます。
MyObject object = new MyObject();//normal way
ClassName ObgRef=ClassName.FactoryMethod();
例:
RunTime rt=Runtime.getRunTime();//Static Factory Method
clone()
を使用することによって、clone()
を使用して既存のオブジェクトのコピーを作成することができます。
MyObjectName anotherObject = new MyObjectName();
MyObjectName object = anotherObjectName.clone();//cloning Object
クラスの名前がわかっていて、それにパブリックのデフォルトコンストラクタがある場合は、この方法でオブジェクトを作成できます。
MyObjectName object = (MyObjectNmae) Class.forName("PackageName.ClassName").newInstance();
例:
String st=(String)Class.forName("Java.lang.String").newInstance();
オブジェクトの逆シリアル化は、シリアル化された形式からオブジェクトを作成することに他なりません。
ObjectInputStreamName inStream = new ObjectInputStreamName(anInputStream );
MyObjectName object = (MyObjectNmae) inStream.readObject();
方法1
新しいキーワードを使用しています。これは、Javaでオブジェクトを作成するための最も一般的な方法です。このようにして、ほぼ99%のオブジェクトが作成されます。
Employee object = new Employee();
方法2
Class.forName()を使用します。 Class.forName()はクラスオブジェクトを返します。これはリフレクションに役立ちます。このオブジェクトが持つメソッドは、クラスを書いているプログラマによってではなく、Javaによって定義されます。それらはすべてのクラスで同じです。その上でnewInstance()を呼び出すと、そのクラスのインスタンスが得られます(つまり、callingClass.forName( "ExampleClass")。newInstance()は、new ExampleClass()を呼び出すのと同じことになり、クラスで定義されているメソッドを呼び出すことができます)。可視フィールドなどにアクセスする.
Employee object2 = (Employee) Class.forName(NewEmployee).newInstance();
Class.forName()は常に呼び出し元のClassLoaderを使用しますが、ClassLoader.loadClass()は別のClassLoaderを指定できます。 Class.forNameはロードされたクラスも初期化しますが、ClassLoader.loadClass()アプローチはすぐには初期化しません(初めて使用されるまで初期化されません)。
別の人は読む必要があります:
Java:例による単純なJava Enumの例によるスレッド状態の紹介
方法3
Clone()を使用してください。 clone()を使って既存のオブジェクトのコピーを作成することができます。
Employee secondObject = new Employee();
Employee object3 = (Employee) secondObject.clone();
方法4
NewInstance()メソッドを使用する
Object object4 = Employee.class.getClassLoader().loadClass(NewEmployee).newInstance();
方法5
オブジェクトの逆シリアル化を使用するオブジェクトの逆シリアル化は、直列化された形式からオブジェクトを作成することに他なりません。
// Create Object5
// create a new file with an ObjectOutputStream
FileOutputStream out = new FileOutputStream("");
ObjectOutputStream oout = new ObjectOutputStream(out);
// write something in the file
oout.writeObject(object3);
oout.flush();
// create an ObjectInputStream for the file we created before
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("crunchify.txt"));
Employee object5 = (Employee) ois.readObject();
APIユーザーの観点からは、コンストラクタの代わりに静的なファクトリメソッド(BigInteger.valueOf()など)を使用することもできますが、APIの作成者(および厳密には「for for」)では、オブジェクトはコンストラクタを使用して作成されます。