Si tengo una clase com.example.test.Enum2.Test
como en el código siguiente, ¿por qué getCanonicalName()
devuelve com.example.test.Enum2.Test
pero Class.forName()
requiere "com.example.test.Enum2$Test"
como argumento?
¿Hay alguna manera de ser consistente, de modo que pueda serializar/deserializar un valor enum por su nombre, sin tener que marcar cada posibilidad de $
frente a .
, cuando la enumeración es una clase anidada?
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());
}
}
aclaración: estoy buscando una buena manera de hacer frente a este problema en una aplicación real (no sólo el caso de prueba artificial arriba), ya sea:
a. serialize/deserialize usando la salida getCanonicalName()
(solo con el nombre punteado), y para Class.forName()
intente cada posibilidad a su vez, p. primero "com.example.test.Enum2.Test"
, luego "com.example.test.Enum2$Test"
, luego "com.example.test$Enum2$Test"
, etc.
b. use la notación $ apropiada, para que Class.forName()
funcione correctamente la primera vez. Pero esto requiere que implemente una alternativa para getCanonicalName() que produzca una cadena que sea coherente con Class.forName()
.
Me inclino por el enfoque (b), parcialmente por la sensación visceral, y en parte porque el enfoque (a) tiene ambigüedades si hay nombres de paquetes con letras mayúsculas: com.example.Test.Enum2 y com.example.Test $ Enum2 pueden ser entradas válidas a Class.forName()
si hay un com/example/Test/Enum2.java, y un com/example/Test.java que contiene una clase interna Enum2.
... pero no sé cómo implementarlo. ¿Algunas ideas?
bummer. por lo que el nombre del idioma! = el nombre de la VM. :-(¿Hay alguna manera más fácil de convertir la notación punteada a la $ correcta, sin tener que probar cada posibilidad por turno? (P.ej. com.example.test.Enum2.Test, com.example.test.Enum2 $ Test, com .example.test $ Enum2 $ Test, etc.) –
@Jason S: No, desafortunadamente es ambiguo. xyz.ABC podría significar 'xyz.ABC', o' xyz.AB $ C', o 'xyz.A $ B $ C' o 'xyz $ A $ B $ C'. La" versión en dólares "no es ambigua. –
ok, gracias, eso es lo que pensé. (+1 para la explicación) –