Java
reflection

java.lang.Voidをインスタンス化するという遊び


趣旨

この記事はjava.lang.Voidのオブジェクトを生成して、

そのオブジェクトのメソッドを呼ぶまでのことをやってみた記事です。

しかし、java.lang.Voidのオブジェクトを生成できてもおそらくなんのメリットも無いと思われますので、ただの遊びです。


コード

解説もコメントに書きました。

import java.lang.reflect.Constructor;

public class CreateVoid {
public static void main(String... args) throws Exception {
//クラス名を文字列で指定してClassを取得する方法です
Class<Void> voidClazz1 = (Class<Void>)Class.forName("java.lang.Void");
Void o1 = getVoid(voidClazz1);

//実際のメソッドからClassを取得する方法です
Class<Void> voidClazz2 = (Class<Void>)CreateVoid.class.getMethod("voidMethod", new Class[]{}).getReturnType();
Void o2 = getVoid(voidClazz2);

System.out.println(o1);//java.lang.Void@1c6b6478
//equalsメソッドをOverrideしていないので、別インスタンスであれば必ずfalseになる
System.out.println(o1.equals(o2));//false
System.out.println(o1.hashCode());//476800120
System.out.println(o1.toString());//java.lang.Void@1c6b6478
System.out.println(o1.getClass());//class java.lang.Void
}

//voidだとプリミティブ型となるので、Void(=java.lang.Void)です。
public Void voidMethod(){return null;};

//Class<Void>からVoidオブジェクトを生成します
private static Void getVoid(Class<Void> voidClazz) throws Exception {
//JDKのソースを覗くと`private Void() {}`とコンストラクターがprivateになっているので以下のようにする必要があります
//1. getConstructorではなくgetDeclaredConstructorと書く
//2. accessibleフラグをtrue
Constructor<?> declaredConstructor = voidClazz.getDeclaredConstructor(new Class[]{});
declaredConstructor.setAccessible(true);
return (Void)declaredConstructor.newInstance(new Object[]{});
}
}