views:

851

answers:

4

In Java, can Class.forName ever return null, or will it always throw a ClassNotFoundException or NoClassDefFoundError if the class can't be located?

+4  A: 

Since null is not mentioned anywhere in the documentation for this method and because there doesn't seem to be any situation in which it would make sense for the method to return null instead of throwing an exception, I think it's pretty safe to assume that it never returns null.

It won't throw a NoClassDefFoundError, but it may throw ClassNotFoundException.

Dan Dyer
Why won't it throw a NCDFError?
Phil
It already throws ClassNotFoundException, it would be confusing if it used both. NoClassDefFoundError is thrown by the VM when it can't find a class in the course of its normal operations. ClassNotFoundException is thrown when a class cannot be found by code that uses reflection.
Dan Dyer
That's not quite true. Class.forName does throw NCDFE, see my response below.
Hemal Pandya
@Hermal: No it doesn't; the JVM throws it in your example trying to resolve a class from a "normal" reference (non reflected); it just happens to percolate through Class.forName(). Any method can see a NCDFError pass through it.
Software Monkey
@Software Monkey: You are correct. Thanks.
Hemal Pandya
+6  A: 

Java Docs says it will return ClassNotFoundException if the class cannot be found so I'd say it never returns null.

willcodejavaforfood
What if you're using a custom classloader?
jdigital
Then the custom classloader is breaking the contract. You'll have to decide if you want to code for that contingency. Similarly if you're using an AOP runtime top rewrite existing classes, like the classloader. :-)
Darron
@Darron: Which contract are you referring to?
Hemal Pandya
@Hemal on Darron: To return ClassNotFoundException.
OscarRyz
Don't know what I am missing. Are you referring to the fact that `Class.forName throws CNFE`? But that does not mean it cannot return null, or that it cannot throw other unchecked exceptions.
Hemal Pandya
A: 

Using the default class loader, surely you will receive no nulls. But, as jdigital says, you may be subject to any number of custom classloaders depending on what security model or other type of proxy loader that you may be using (intentionally or otherwise).

Heck, even forName can take a ClassLoader as a parameter... :)

Piko

Piko
Well if you're using a "bad" custom class loader, you can get a Cow for that matter!! :)
OscarRyz
This answer would only be accurate for a class loader which breaks it's documented contract - I wouldn't bother coding for that.
Software Monkey
A: 

@Dan Dyer is wrong, Class.forName can throw NoClassDefFoundError, if the class it is trying gets a ClassNotFoundException error in its static initialiazer. The following is unte

class Outer {
  public static final void main(final String[] args) throws Exception{
    Class.forName("Inner");
  }
}

If you compile and run this in a directory with no other file you get ClassNotFoundException: Inner

Now add the following to in the same directory, compile everything and java Outer once to see it runs ok.

class Inner {
  static Inner2 _i2 = new Inner2();
}

class Inner2 {}

Finally, delete Inner2.class and rerun Outer, you will get NoClassDefFoundError: Inner2, caused by ClassNotFoundException: Inner2

Hemal Pandya
No it doesn't; the JVM throws it in your example trying to resolve a class from a "normal" reference (non reflected); it just happens to percolate through Class.forName(). Any method can see a NCDFError pass through it.
Software Monkey
Hmmm. Yes, I see what you are saying. It's like saying Class.forName throws NPE or OOME, because the class to be loaded throws it in its clinit.
Hemal Pandya
"@Dan Dyer is wrong" is not a great way to answer a question from Phil.
Tom Hawtin - tackline
Yes, it should have been a comment to Dan's answer. But I wanted to formatted code so I used a separate entry. Of course, I was wrong in saying Dan is wrong. Look at the benefit: as bonus, I also got a few downvotes :-)
Hemal Pandya