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.

Federer
źródło
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;
Bozho
źródło
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

siegi
źródło
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()
sfussenegger
źródło
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ą.

sepp2k
źródło
-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.

4teks
źródło
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,