Zmień nazwę importu w Javie lub zaimportuj dwie klasy o tej samej nazwie


363

W Pythonie możesz wykonać:

from a import b as c

Jak zrobiłbyś to w Javie, ponieważ mam dwa sprzeczne ze sobą importy.


19
Chciałbym, żeby java to zrobiła. Prowadzi do zajęć o dziwnych nazwach.
fncomp

2
@fncomp: .. i niechlujny kod z dużą ilością w pełni kwalifikowanych
nazw klas

2
Java 12 nadal tego nie ma
Janac Meena

Odpowiedzi:


463

W Javie nie ma mechanizmu aliasingu importu. Nie można zaimportować dwóch klas o tej samej nazwie i używać obu bez zastrzeżeń.

Zaimportuj jedną klasę i użyj w pełni kwalifikowanej nazwy dla drugiej, tj

import com.text.Formatter;

private Formatter textFormatter;
private com.json.Formatter jsonFormatter;

16
To właściwa odpowiedź i do tego dodam tylko to, co sugerujesz: nie, nie ma takiej składni aliasingu w Javie.
Sean Owen,

19
Czy nadal jest to ograniczenie w Javie 8?
HairOfTheDog

8
@HairOfTheDog Nope, niestety nie dodano aliasingu importu w Javie8
AdrieanKhisbe

12
Tak, zgadzam się z twoim komentarzem linuxdan ... Java poszła drogą dinozaura pod względem aktualizacji jego składni.
Kevin Parker

6
@Bozho Sposób pyton robi: import [fully-qualified-name] as [ident]. „Jak” słowo kluczowe wydaje się nie pasować w Javie, a także alternatywny jest w przybliżeniu jakie używa C #: import [ident] = [fully-qualified-name].
Daniel H

60

Jak już wspomniano w innych odpowiedziach, Java nie udostępnia tej funkcji.

Wdrożenie tej funkcji było wymagane wielokrotnie, np. Jako JDK-4194542: aliasing nazwy klasy lub JDK-4214789: Rozszerz import, aby umożliwić zmianę nazwy importowanego typu .

Z komentarzy:

To nie jest nierozsądna prośba, choć nie jest niezbędna. Sporadyczne użycie w pełni kwalifikowanych nazw nie stanowi nadmiernego obciążenia (chyba że biblioteka rzeczywiście używa tych samych prostych nazw w prawo i w lewo, co jest złym stylem).

W każdym razie nie zmienia poprzeczki cena / wydajność w przypadku zmiany języka.

Sądzę więc, że wkrótce nie zobaczymy tej funkcji w Javie :-P


15
łał! nie żartowałeś z powodu „nie (…) w najbliższym czasie”). Widzę, że prośba o funkcję została odrzucona jako bezcelowy cukier już w 1998 roku! I każda próba wznowienia dyskusji w ciągu ostatnich 18 lat wiązała się z odniesieniem do tej starożytnej decyzji. Wydaje mi się, że łatwiej byłoby przekonać programistów IDE do zaimplementowania tego jako maski w edytorze, niż próbować wbić sens w Oracle.
Superole,

2
Stare rozumowanie jest jednak poprawne - w praktyce takie starcia występują bardzo rzadko.
szczupły

14
Nie zgadzam się, że te starcia występują rzadko. Orientacja obiektowa sprzyja prostemu nazywaniu. Mogę mieć pracownika klasy z dwóch różnych bibliotek, które robią różne rzeczy z pracownikiem (na przykład).
Andrei Epure

6
@slim „ w praktyce te starcia występują bardzo rzadko ”. To nie jest dla mnie jasne, dlaczego te sytuacje będą występować rzadziej w Javie (w którym można mieć 10.000+ klas) niż w innych językach (gdzie zwykle mają mniej klas), które zrobienia obsługuje tej składni „cukier”.
Alain Pannetier

21
Absolutnie niepoprawne. Mam do czynienia z bardzo prostym scenariuszem, który prawdopodobnie jest bardzo powszechny i ​​w którym ten cukier składniowy byłby niezwykle pomocny. Tłumaczenie między podobnymi, ale odrębnymi modelami obiektowymi (stosowanymi odpowiednio w powiązanych, ale różnych produktach), których klasy przez większość czasu mają tę samą nazwę. Proces tłumaczenia wymaga odwołania się do obu klas w tym samym bloku kodu. W takim przypadku (który musi być bardzo powszechny) Java bardzo utrudnia życie. Tylko liczba wyświetleń tego postu powinna opowiedzieć historię.
hrshi1990

59

Prawdopodobnie warto zauważyć, że Groovy ma tę funkcję :

import java.util.Calendar
import com.example.Calendar as MyCalendar

MyCalendar myCalendar = new MyCalendar()

15
W Scali jest to:import com.example.{Calendar => MyCalendar}
pablisco

24
Aw Kotlin: import com.example.Calendar as MyCalendar.
KevinO

14
W PHP jest to: użyj com \ example \ Calendar jako MyCalendar
mat

19
Dość denerwujące jest to, że (przynajmniej) 3 języki oparte na JVM (Groovy, Scala i Kotlin) mają tę funkcję, ale sama Java wciąż nie ma ...
Matthias

2
Co powiesz na coś takiego class MyCalendar extends com.example.Calendar {}? Nie jest idealny ani ładny, ale powinien służyć większości celów bez, powiedzmy, refleksji. W razie potrzeby możesz nawet dodać komentarz z komentarzem /* import com.example.Calendar as MyCalendar */.
Braden Best

21

Java nie pozwala na to. Musisz odwoływać się do jednej z klas za pomocą jej w pełni kwalifikowanej nazwy i importować tylko drugą.



-4

W rzeczywistości można utworzyć skrót, aby można było używać krótszych nazw w kodzie, wykonując coś takiego:

package com.mycompany.installer;
public abstract class ConfigurationReader {
    private static class Implementation extends com.mycompany.installer.implementation.ConfigurationReader {}
    public abstract String getLoaderVirtualClassPath();
    public static QueryServiceConfigurationReader getInstance() {
        return new Implementation();
    }
}

W ten sposób wystarczy tylko raz podać długą nazwę i mieć tyle dowolnych nazwanych klas.

Inną rzeczą, która podoba mi się w tym wzorze jest to, że możesz nazwać klasę implementującą tak samo jak abstrakcyjną klasę podstawową i po prostu umieścić ją w innej przestrzeni nazw. Nie ma to jednak związku ze wzorcem importu / zmiany nazwy.


18
To bardzo złe rozwiązanie. Zupełnie nie radzi sobie ze statyką, może wymagać ciągłych aktualizacji i nie pomaga w problemach de / serializacji (takich jak deserializacja z xml przez jaxb).
Inżynier oprogramowania,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.