Jeśli mam klasę com.example.test.Enum2.Test
jak w poniższym kodzie, dlaczego getCanonicalName()
zwraca com.example.test.Enum2.Test
, ale Class.forName()
wymaga "com.example.test.Enum2$Test"
jako argumentu?
Czy istnieje sposób, aby być spójne, tak że mogę serializacji/deserializacji wartość enum od jego nazwy, bez konieczności sprawdzenia każdego $
vs .
możliwość, gdy enum jest zagnieżdżona klasa?
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());
}
}
wyjaśnienia: szukam dobry sposób na radzenie sobie z tym problemem w rzeczywistej aplikacji (nie tylko powyższy wymyślony przypadków testowych), albo:
się. serializować/deserializować przy użyciu wyjścia getCanonicalName()
(tylko nazwa kropkowana), a dla Class.forName()
wypróbować każdą możliwość po kolei, np. najpierw "com.example.test.Enum2.Test"
, następnie "com.example.test.Enum2$Test"
, następnie "com.example.test$Enum2$Test"
, itp.
b. użyj poprawnej notacji $, aby Class.forName()
działała poprawnie za pierwszym razem. Wymaga to jednak zastosowania alternatywy dla metody getCanonicalName(), która tworzy ciąg zgodny z Class.forName()
.
Pochylam się do podejścia (b), częściowo z powodu odczuwania jelit, częściowo dlatego, że podejście (a) ma niejasności, jeśli istnieją nazwy pakietów z wielkimi literami: com.example.Test.Enum2 i com.example.Test $ Enum2 może być zarówno poprawnymi danymi wejściowymi do Class.forName()
, jeśli istnieje com/example/Test/Enum2.java, a com/example/Test.java zawierające wewnętrzną klasę Enum2.
... ale nie wiem jak to zrobić. Jakieś pomysły?
bummer. więc nazwa języka! = nazwa maszyny wirtualnej. :-(Czy istnieje prostszy sposób na konwersję notacji kropkowanej na właściwe $, bez konieczności wypróbowywania każdej kolejnej opcji (np. Com.example.test.Enum2.Test, com.example.test.Enum2 $ Test, com .example.test $ Enum2 $ Test, itp.) –
@Jason S: Nie, niestety jest niejednoznaczna xyz.ABC może oznaczać 'xyz.ABC', lub' xyz.AB $ C' lub 'xyz.A $ B $ C' lub 'xyz $ A $ B $ C'." Wersja dolara "jest jednak jednoznaczna –
OK, dziękuję, to właśnie myślałem. (+1 dla wyjaśnienia) –