以前、JavaのSystem.out.printlnと書くのが面倒だという人がいた。なので、System.out.print系を書かずにHello Worldを出力するプログラムを考えてみた。
public class Test{ public static void main(String[] args){ throw new RuntimeException("Hello World"); } }
ああ、嘘です。ごめんなさい。他にもいくつか考えたけど、もっと真面目にやります。ではどうぞ↓。ほら、System.out.printlnどころかSystemとすら書かずに標準出力にメッセージが!勿論、System.out.printlnを使ってるんだけどね!
import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException ; import java.util.Stack; public class Hello{ private static final char[] SOURCE; static{ StringBuilder builder = new StringBuilder(); builder.append("auiiiiiiiaiiiiaiiiiiiiiiiiaiiiiiiiiiiiai"); builder.append("iiiiiiiiiiiiiauddddddddddddddddddddddddd"); builder.append("ddddddddauiiiiiiiiiiiiiiiiiiiiiiaiiiiiii"); builder.append("iiiiiiiaiiiiiiiiiiiiiiiiiaiiiiiiiiiiiaii"); builder.append("ipnipaiiiiiiiiiiiiiiiaiiiiiiiiiiiiiiiiia"); builder.append("iiiiiiiiaiiiiiiiiiiiiiaiiiiiiiiiiiiiiiii"); builder.append("iiaiiiiiiiiiiiaiiiiiiiiiiiiipaiiiiiiiiia"); builder.append("aiiiiiiiiiiiiiiiiiiiiiaauddddddddddddddd"); builder.append("ddddaiiiiiiiiaiiiiiiiiiiiiiiaudddddddddd"); builder.append("dddddddddauiiiiiiiiiiiiiiiaiiiiiiiiiiiii"); builder.append("iiiiaiiiiiiiiaiiiiiiiiiiiiiaiiiiiiiiiiii"); builder.append("iiiiiiiauiiiiiiiiiiiiiiiiiiaiiiiiiiiiiii"); builder.append("iiiiiiiaiiiiiiiiiiiiiiiiiaiiiiaaiiiiiiii"); builder.append("iiiipaiiiiiiiiiiiiiiaiiiiiiiiiiiiiiiiiii"); builder.append("iaiiiiiiiiiiiiiiiiiiipaiiiiiiiiiaaiiiiii"); builder.append("iiiiiiiiiiiiiiiaaudddddddddddddddddddaii"); builder.append("iiiiiiiiiaaiiiiiiiiiiiiiaiiiiiiauddddddd"); builder.append("ddddddddddddauiiiiiiiiiiiiiiiiiiaiiiiiii"); builder.append("iiiiiiiiiiiiiiiiiaiiiiiiiiiiiiiiiiiiaiii"); builder.append("iiiiiiiiiiiiiiiiaiiiiaiiiiiiiiiiiipgm"); SOURCE = builder.toString().toCharArray(); } public static void main(String[] args) throws Exception{ Hello.execute(Hello.SOURCE); } private static void execute(char[] program) throws Exception{ int index = 0; char[] text = new char[4096]; int textIndex = -1; int number = -1; Stack<Object> stack = new Stack<Object>(); while(index != program.length){ switch(program[index]){ case 'a': textIndex++; text[textIndex] = 'a'; break; case 'n': textIndex = -1; number = 0; break; case 'x': textIndex = -1; number = Integer.MAX_VALUE; break; case 'i': if(textIndex > -1){ text[textIndex]++; }else{ number++; } break; case 'd': if(textIndex > -1){ text[textIndex]--; }else{ number--; } break; case 'u': text[textIndex] = Character.toUpperCase(text[textIndex]); break; case 'l': text[textIndex] = Character.toLowerCase(text[textIndex]); break; case 'p': if(textIndex > -1){ stack.push(new String(text, 0, textIndex + 1)); textIndex = -1; } else{ stack.push(number); number = -1; } break; case 'o': stack.pop(); break; case 'c': stack.push(Hello.callConstructor(stack)); break; case 'm': stack.push( Hello.invokeMethod(stack, false)); break; case 's': stack.push( Hello.invokeMethod(stack, true)); break; case 'f': stack.push(Hello.getField(stack, false)); break; case 'g': stack.push( Hello.getField(stack, true)); break; default: break; } index++; } } private static Object callConstructor(Stack<Object> stack) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { String className = stack.pop().toString(); String parameter = stack.pop().toString(); int parameterCount = 0; if(parameter.equals("type")){ parameterCount = Integer.parseInt(stack.pop().toString()); return Hello.callConstructorWithType(stack, className, parameterCount); }else{ parameterCount = Integer.parseInt(parameter); return Hello.callConstructorWithoutType(stack, className, parameterCount); } } private static Object callConstructorWithType(Stack<Object> stack, String className, int parameterCount) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Class<?>[] types = new Class<?>[parameterCount]; Object[] args = new Object[parameterCount]; for(int i = 0; i < parameterCount; i++){ types[i] = Class.forName(stack.pop().toString()); } for(int i = 0; i < parameterCount; i++){ args[i] = stack.pop();; } return Hello.callConstructor(className, types, args); } private static Object callConstructorWithoutType(Stack<Object> stack, String className, int parameterCount) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Class<?>[] types = new Class<?>[parameterCount]; Object[] args = new Object[parameterCount]; for(int i = 0; i < parameterCount; i++){ Object arg = stack.pop(); types[i] = arg.getClass(); args[i] = arg; } return Hello.callConstructor(className, types, args); } private static Object callConstructor(String className, Class<?>[] types, Object[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Class<?> clazz = Class.forName(className); Constructor constructor = clazz.getConstructor(types); return constructor.newInstance(args); } private static Object invokeMethod(Stack<Object> stack, boolean isStatic) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { Object target = null; if(!isStatic) target = stack.pop(); String className = stack.pop().toString(); String methodName = stack.pop().toString(); String parameter = stack.pop().toString(); int parameterCount = 0; if(parameter.equals("type")){ parameterCount = Integer.parseInt(stack.pop().toString()); return Hello.invokeMethodWithType(stack, target, className, methodName, parameterCount); }else{ parameterCount = Integer.parseInt(parameter); return Hello.invokeMethodWithoutType(stack, target, className, methodName, parameterCount); } } private static Object invokeMethodWithType(Stack<Object> stack, Object target, String className, String methodName, int parameterCount) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException{ Class<?>[] types = new Class<?>[parameterCount]; Object[] args = new Object[parameterCount]; for(int i = 0; i < parameterCount; i++){ types[i] = Class.forName(stack.pop().toString()); } for(int i = 0; i < parameterCount; i++){ args[i] = stack.pop();; } return Hello.invokeMethod(className, target, methodName, types, args); } private static Object invokeMethodWithoutType(Stack<Object> stack, Object target, String className, String methodName, int parameterCount) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException{ Class<?>[] types = new Class<?>[parameterCount]; Object[] args = new Object[parameterCount]; for(int i = 0; i < parameterCount; i++){ Object arg = stack.pop(); types[i] = arg.getClass(); args[i] = arg; } return Hello.invokeMethod(className, target, methodName, types, args); } private static Object invokeMethod(String className, Object target, String methodName, Class<?>[] types, Object[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { Class<?> clazz = Class.forName(className); Method method = clazz.getMethod(methodName, types); return method.invoke(target, args); } private static Object getField(Stack<Object> stack, boolean isStatic) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException{ Object target = null; if(!isStatic) target = stack.pop(); String className = stack.pop().toString(); String fieldName = stack.pop().toString(); return Hello.getField(className, target, fieldName); } private static Object getField(String className, Object target, String fieldName) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException{ Class<?> clazz = Class.forName(className); Field field = clazz.getField(fieldName); return field.get(target); } }