Why does Class.isLocalClass always Boolean.FALSE?

1.5k Views Asked by At

I've got a simple Method that returns me always "-undefined-".

public static String getStereoType(Class<?> clazz) {
    String result = "-undefined-";
    if (clazz.isEnum()) {
        result = "enum";
    } else if (clazz.isInterface()) {
        result = "interface";
    } else if (clazz.isLocalClass() || clazz.isMemberClass()) {
        result = "class";
    }
    return result;
}

When I call this Method with Object.class or Long.class always is the result "-undefined-".

 List<Class<?>> superClazzes = ClassUtil.getSuperClazzList(clazz);
    for (Class<?> c: superClazzess){
        String stereoType = ClassUtil.getStereoType(c.getClass());
        }

public static List<Class<?>> getSuperClazzList(Class<?> clazz) {
        List<Class<?>> resultList = new ArrayList<Class<?>>();
        Class<?> superClass = clazz.getSuperclass();
        if (superClass != null) {
            resultList.add(superClass);
            resultList.addAll(getSuperClazzList(superClass));
        }
        return resultList;
    }
2

There are 2 best solutions below

2
On

What are you trying to get? So what are the possible stereo types you need? What I know of is:

  • Enum
  • Interface
  • Primitive (e.g. double, but not Double)
  • Class (everything else!)

And from the class API I can find that you might also differ between:

  • annotation (actual an interface in java)
  • synthetic (I'm not sure what this is)
  • local (defined inside a method)

But they might not be interesting for ULM diagrams at all.

Implementation of toString() from the JVM Class is:

public String toString() {
    return (isInterface() ? "interface " : (isPrimitive() ? "" : "class ")) + getName();
}

This might give you some hint as well.

Hope it helps.

Edit: This should do the job:

public static String getStereoType(Class<?> clazz) {
        String result = "class";
        if (clazz.isEnum()) {
            result = "enum";
        } else if (clazz.isInterface()) {
            result = "interface";
        } 
        else if (clazz.isPrimitive()) {
            result = "primitive";
        }

        return result;
    }
0
On

To answer the question in your title, isLocalClass() does not always return false: it returns true for types declared within a method. Similarly, isMemberClass() returns true for types declared within another type.

Consider:

public class Outer {

    interface MemberClass {}

    public static void main(String[] args) {
        class LocalClass {}

        System.out.printf(
            "%s/%s%n",
            LocalClass.class.isLocalClass(),
            LocalClass.class.isMemberClass()
        );

        System.out.printf(
            "%s/%s%n",
            MemberClass.class.isLocalClass(),
            MemberClass.class.isMemberClass()
        );
    }
}

This code, when executed, prints out true/false followed by false/true. Together, they only account for types which are defined within another class, or within a method. Neither strictly depends on the target type being a class as opposed to an interface or enum, so you cannot use it to filter that way.

See @Tarion's excellent answer for the approach you should be taking (and accept his answer, as it more completely solves your problem).