iconst, iload, iadd, and invokevirtual are the real opcodes defined in the JVM Specification's instruction set, and the fetch-decode-execute loop you're writing is a miniature version of what HotSpot's bytecode interpreter (the C++ templateInterpreter) does before a method gets hot enough for JIT compilation. This is the same exercise behind small educational JVMs like avian and the various 'write your own JVM' community projects.