Javaだって簡単にFizzBuzz書けるもん! ~ 匿名クラス利用

  • 9
    いいね
  • 2
    コメント
この記事は最終更新日から1年以上が経過しています。

もうちょっと簡単なFizzBuzzを探ってみました。

ではコードをどうぞ。

package reflect2;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class FizzBuzz
{
    public static interface Dummy
    {
        default CharSequence trans(int i)
        {
            return "" + i;
        }
    }

    public static void main(String[] args)
        throws Exception
    {
        new Dummy(){{
            new Dummy(){
                @Override
                public CharSequence trans(int i)
                {
                    return "FizzBuzz";
                }
            };
            new Dummy(){
                @Override
                public CharSequence trans(int i)
                {
                    return "Buzz";
                }
            };
            new Dummy(){
                @Override
                public CharSequence trans(int i)
                {
                    return "Buzz";
                }
            };
        }};
        new Dummy(){{
            new Dummy(){
                @Override
                public CharSequence trans(int i)
                {
                    return "Fizz";
                }
            };
            new Dummy(){};
            new Dummy(){};
        }};
        new Dummy(){{
            new Dummy(){
                @Override
                public CharSequence trans(int i)
                {
                    return "Fizz";
                }
            };
            new Dummy(){};
            new Dummy(){};
        }};
        new Dummy(){{
            new Dummy(){
                @Override
                public CharSequence trans(int i)
                {
                    return "Fizz";
                }
            };
            new Dummy(){};
            new Dummy(){};
        }};
        new Dummy(){{
            new Dummy(){
                @Override
                public CharSequence trans(int i)
                {
                    return "Fizz";
                }
            };
            new Dummy(){};
            new Dummy(){};
        }};

        for(int i= 1; i <= 100; ++i)
        {
            final Class<?> declaringClazz= Class.forName(FizzBuzz.class.getName() + "$" + (i % 5 + 1));
            final Class<?> clazz= Class.forName(FizzBuzz.class.getName() + "$" + (i % 5 + 1) + "$" + (i % 3 + 1));

            final Constructor<?> ctor= clazz.getDeclaredConstructor(declaringClazz);
            final Method trans= clazz.getMethod("trans", int.class);

            System.out.println(trans.invoke(ctor.newInstance(declaringClazz.newInstance()), i));
        }
    }
}

匿名クラスはjavacされると、ソース中の上から順に\$1、\$2のように連番で.classファイルが生成されることを利用しています。
匿名クラスをネストさせることで、FizzBuzz\$1\$2のような多重配列のようなものを作り出し、Class.forName()で匿名クラスにアクセスしています。
匿名クラスはそれぞれtrans()で返却する文字列が適当なものになっているため、順次それらを呼び出すことでFizzBuzzっています。

Javaでも簡単なFizzBuzzが書けたよ!

ということでgithubにも上げてあります。
こちらからどうぞ。