samedi 7 décembre 2019

Initialize (load) a java class with a java.lang.Class

I have to admit that this is more a cosmetic issue, but the fact that I haven't found a more straight-forward solution makes me think I am probably missing something.

The thing is, my class (let's say Foo) has a very important static block where it registers itself (Foo.class) with a builder method in a Map, like this:

// somewhere in the class
static {
    Bar.registerBuilder(Foo.class, Foo::build);
}

This makes it possibe to get a Foo builder from the Bar class, a bit like this:

// somewhere in a method
Foo foo = Bar.getBuilder(Foo.class).apply("Hello World");

(if the builder takes a String argument). However, the upper code example will only work if the Foo class was already initialized. If not, this means the static block of Foo wasn't executed and the builder isn't registered in Bar by now, which is leading to getBuilder() returning null and apply() throwing a NullPointerException.

Thanks to the internet (mostly StackOverflow) I found out that you can imperatively with Class.forName(String). But what really confuses me is that this method takes a String (therefore throws the checked ClassNotFoundException) and I haven't found a way to load and initialize a class directly via a java.lang.Class instance. I would have expected something like

Class<Foo> clazz = Foo.class;
clazz.load(); // does not exist

Instead I have to do this:

Class<Foo> clazz = Foo.class;
try {
    Class.forName(clazz.getName());
} catch (ClassNotFoundException) {
    // handle an exception that is actually unreachable
}

I would like to know if I am completely missing something, or if not, if there is a cleaner way to load and initialize a class via the java.lang.Class representation.

Any help is appreciated, thank you!

EDIT 1: As @Boris the Spider pointed out in the comments, Foo.class should probably already load and initialize the class, but it doesn't (in my case, at least) and that's why I even encountered this problem.

EDIT 2: Using the "complicated" way to load the class via Class.forName() (as in the code example) actually resolves the problem as I thought. It's just that I'd like to use a cleaner way if possible.

Using:

  • Java 11 (openjdk 11.0.2)
  • IntelliJ IDEA Ultimate (2019.3)
  • Maven (3.6.3)




Aucun commentaire:

Enregistrer un commentaire