The question is whether you want to write custom bytecode in a human friendly format, or if you want to literally write a binary classfile by hand.
If you want to write a binary file by hand, you obviously need a Hex Editor. I've written classfiles directly in a hex editor before, and it is a very annoying and error prone process, and it is not really feasible for anything more complicated than Hello World.
Luckily, I've written an assembler which allows you to write bytecode in a human friendly textual form and assemble it to binary classfiles. Unlike other Java bytecode assemblers, Krakatau gives you very low level control over the results and is designed to support the full classfile format, as well as some undocumented features that the JVM accepts in practice.
This allows you to do pretty much anything you might want to, while Krakatau automatically handles the low level file format details and binary encoding for you. It's as close as you can get to directly writing a classfile, short of doing it by hand in a hex editor.
Here is an example of an assembly file for a Hello World program using the v0 Krakatau syntax.
.class public hello
.super java/lang/Object
.method public static main : ([Ljava/lang/String;)V
.limit stack 10
.limit locals 10
getstatic java/lang/System out Ljava/io/PrintStream;
ldc "Hello World!"
invokevirtual java/io/PrintStream println (Ljava/lang/Object;)V
return
.end method