LoginSignup
1

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-08-19

趣旨

この記事は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[]{});
    }
}

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1