If I have a class com.example.test.Enum2.Test as in the code below, why does getCanonicalName() return com.example.test.Enum2.Test but Class.forName() requires "com.example.test.Enum2$Test" as an argument?

Is there a way to be consistent, so that I can serialize/deserialize an enum value by its name, without having to check each $ vs . possibility, when the enum is a nested class?

package com.example.test;

import java.util.Arrays;

public class Enum2 {

    enum Test {
        FOO, BAR, BAZ;
    }

    public static void main(String[] args) {
        for (String className : Arrays.asList(
                "com.example.test.Enum2.Test",
                "com.example.test.Enum2$Test"))
        {
            try {
                Class<?> cl = Class.forName(className);
                System.out.println(className+" found: "+cl.getCanonicalName());
            }
            catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }

        System.out.println(Test.FOO.getDeclaringClass().getCanonicalName());
    }
}

clarification: I'm looking for a good way to deal with this problem in a real application (not just the above contrived test case), either:

a. serialize/deserialize using getCanonicalName()'s output (dotted name only), and for Class.forName() try each possibility in turn e.g. first "com.example.test.Enum2.Test", then "com.example.test.Enum2$Test", then "com.example.test$Enum2$Test", etc.

b. use proper $ notation, so that Class.forName() works right the first time. But this requires me to implement an alternative to getCanonicalName() that produces a string that is consistent with Class.forName().

I am leaning toward approach (b), partially from gut

Edit
Report