Jak uzyskać aktualną nazwę klasy, w tym nazwę pakietu w Javie?

82

Pracuję nad projektem i jednym z wymagań jest to, że drugi argument dla metody głównej zaczyna się od „ /” (dla systemu Linux), powinien traktować go jako ścieżkę bezwzględną (nie jest to problem), ale jeśli nie zaczyna się od „” /”, Powinien pobrać aktualną ścieżkę roboczą klasy i dołączyć do niej podany argument.

Mogę dostać nazwę klasy na kilka sposobów: System.getProperty("java.class.path"), new File(".")i getCanonicalPath(), i tak dalej ...

Problem polega na tym, że to daje mi tylko katalog, w którym przechowywane są pakiety - tj. Jeśli mam klasę zapisaną w " .../project/this/is/package/name", dałoby mi to tylko " /project/" i ignoruje nazwę pakietu, w którym faktycznie znajduje się .class files.

Jakieś sugestie?

EDYCJA: Oto wyjaśnienie zaczerpnięte z opisu ćwiczenia

sourcedir może być bezwzględne (zaczynając od „/”) lub względne w stosunku do miejsca, z którego uruchamiamy program

sourcedir jest podanym argumentem dla metody głównej. jak mogę znaleźć tę ścieżkę?

La bla bla
źródło
2
Co zrobisz, jeśli kod jest spakowany w JAR (lub w inny sposób nie znajduje się w strukturze folderów / plików, jak zakładasz)? To niebezpieczne założenie; może to zadziałać dobrze w przypadku małego eksperymentu, przypisania do klasy lub innej sytuacji jednorazowej, ale PROSZĘ nie nabrać nawyku robienia tego założenia dla kodu jakości produkcyjnej.
E-Riz
Nie ma sensu szukać ścieżki do pliku klasy. Również w opisie ćwiczenia nie ma wzmianki o tym, jeśli się go uważnie przeczytało ( gdzie uruchamiamy program oznacza bieżącą ścieżkę, z której program jest wywoływany przez użytkownika).
The Nail
Może mógłbyś mi pomóc lepiej zrozumieć wymagania? Muszę sprawdzić, czy argument zaczyna się od „/” (wzmianka w opisie). jeśli tak, po prostu użyj go jako wartości bezwzględnej. jak jest. ale jeśli nie, jak mam to leczyć?
La bla bla

Odpowiedzi:

166

Użyj, this.getClass().getCanonicalName()aby uzyskać pełną nazwę klasy.

Zwróć uwagę, że nazwa pakietu / klasy („abC”) różni się od ścieżki do plików .class (a / b / C.class) i że używanie nazwy pakietu / nazwy klasy do tworzenia ścieżki jest zazwyczaj złą praktyką. Zestawy plików / pakietów klas mogą znajdować się w wielu różnych ścieżkach klas, którymi mogą być katalogi lub pliki jar.

Paznokieć
źródło
dzięki, ale jest w głównej metodzie, a „this” nie może być używane w metodach statycznych. jakieś obejście tego?
La bla bla
30

Jest klasa Class, która może to zrobić:

Class c = Class.forName("MyClass"); // if you want to specify a class
Class c = this.getClass();          // if you want to use the current class

System.out.println("Package: "+c.getPackage()+"\nClass: "+c.getSimpleName()+"\nFull Identifier: "+c.getName());

Gdyby creprezentował klasę MyClassw pakiecie mypackage, powyższy kod wypisałby:

Pakiet: mypackage
Klasa: MyClass
Pełny identyfikator: mypackage.MyClass

Możesz pobrać te informacje i zmodyfikować je zgodnie z potrzebami lub przejść do interfejsu API, aby uzyskać więcej informacji.

Jon Egeland
źródło
1
Zauważ, że Class.forName ("MyClass") będzie działać tylko wtedy, gdy znajduje się w pakiecie domyślnym (tj. Nie ma deklaracji pakietu).
The Nail
2
@TheNail true i getName()zwraca nazwę pakietu wraz z nazwą klasy, edytując teraz.
Jon Egeland
Użyj, getSimpleName()aby uzyskać tylko nazwę klasy bez nazwy pakietu.
The Nail
1
Zamiast tego Class.forName("MyClass")powinieneś używać, MyClass.classchyba że naprawdę potrzebujesz wykrywania środowiska wykonawczego z innego powodu.
mjaggard
12

W pełni kwalifikowana nazwa jest dostępna w następujący sposób:

String fqn = YourClass.class.getName();

Ale musisz przeczytać zasób ścieżki klas. Więc użyj

InputStream in = YourClass.getResourceAsStream("resource.txt");
Bozho
źródło
3

użyj, this.getClass().getName()aby uzyskać packageName.classNamei użyj, this.getClass().getSimpleName()aby uzyskać tylko nazwę klasy

Md. Zahangir Alam
źródło