Search code examples
javareflectionclassnotfoundexceptionclassname

Get the fully-qualified name of a class in Java, Class.forName


I want to recognize the class type from a string given through the command line. For example, args[0] = "Integer",

Now I do in this way:

Class<?> cls = Class.forName(args[0]);

But I get "java.lang.ClassNotFoundException: Integer"

I have read that I have to use the fully-qualified name of a class in the forName(), so how can I get the string "java.lang.Integer" from the string "Integer", or "java.util.ArrayList" from "ArrayList", etc?


Solution

  • In Java, String, Integer or even BufferedInputStream are meaningless words defined by programmers. The way Java runs, it needs a fully qualified name in order to be able to distinguish java.lang.String from, for example, kotlin.String (a different language that also runs on the JVM).

    This is why java.lang.String is not only a name, but also points the JVM to a package and more importantly, this packages are represented in the file structure.

    This is why using class names is invalid syntax in Java unless the class is in the same package (in which case, Java can find it using your current package declaration) or if there is an import at the top (which will provide Java a fully qualified name to refer to)

    In short, unless you have a set of rules where you can dynamically provide the fully qualified name, based on the short name, there's not much you could do.

    Here's a short demo of a tiny script that will loop through a couple of common packages to tell you where common Java classes are:

    
    public static void getFullyQualifiedClassName(String className) {
            String[] commonPackages = {"java.lang", "java.util", "java.io", "java.math", "java.nio", "java.net"};
            String qualifiedName;
            for (String packageName : commonPackages) {
                try {
                    Class.forName(packageName + "." + className).getName();
                    System.out.println("A class with that name was found at: " + packageName);
                } catch (ClassNotFoundException e) {
                    System.out.println("The class is not in package " + packageName);
                }
            }
    
    

    Given the input Integer, the following output occurs:

    A class with that name was found at: java.lang.Integer
    The class is not in package java.util
    The class is not in package java.io
    The class is not in package java.math
    The class is not in package java.nio
    The class is not in package java.net
    

    This is probably not useful as you still need to know the possible packages in advance, but maybe it can point you in the right direction