Изменить имя импорта в Java или импортировать два класса с одинаковым именем

363

В Python вы можете сделать:

from a import b as c

Как бы вы сделали это на Java, так как у меня два импорта, которые конфликтуют.

Федерер
источник
19
Я хотел бы, чтобы Java сделал это. Приводит к классам с неловкими именами.
fncomp
2
@fncomp: ..и грязный код с множеством полностью определенных
имен классов
2
У Java 12 до сих пор этого нет
Janac Meena

Ответы:

463

В Java нет механизма псевдонимов импорта. Вы не можете импортировать два класса с одним и тем же именем и использовать оба из них без оговорок.

Импортируйте один класс и используйте полное имя для другого, т.е.

import com.text.Formatter;

private Formatter textFormatter;
private com.json.Formatter jsonFormatter;
Bozho
источник
16
Это правильный ответ, и к этому я бы добавил только то, что вы подразумевали: нет, в Java нет такого синтаксиса псевдонимов.
Шон Оуэн
19
Это все еще ограничение в Java 8?
HairOfTheDog
8
@HairOfTheDog Нет, к сожалению, в Java8 не было добавлено псевдонимов для импорта
AdrieanKhisbe,
12
Да, я согласен с вашим комментарием linuxdan ... Java прошла путь динозавра с точки зрения обновления его синтаксиса.
Кевин Паркер
6
@Bozho Путь питон делает: import [fully-qualified-name] as [ident]. « Как» ключевое слово , кажется, не вписывается в Java , а также, альтернатива примерно то , что # использует C: import [ident] = [fully-qualified-name].
Даниэль Х
60

Как уже говорилось в других ответах, Java не предоставляет эту функцию.

Реализация этой функции запрашивалась несколько раз, например, как JDK-4194542: псевдоним имени класса или JDK-4214789: расширение импорта, чтобы разрешить переименование импортируемого типа .

Из комментариев:

Это не необоснованный запрос, хотя вряд ли существенный. Случайное использование полностью определенных имен не является излишним бременем (если библиотека действительно не использует одни и те же простые имена справа и слева, что является плохим стилем).

В любом случае, это не проходит планку цена / производительность для изменения языка.

Поэтому я думаю, что мы не увидим эту функцию в Java в ближайшее время :-P

siegi
источник
15
Вот Это Да! Вы не шутили насчет "не (...) в ближайшее время", я вижу, что запрос на функцию был отклонен как бессмысленный сахар еще в 1998 году! И каждая попытка возобновить дискуссию в течение последних 18 лет наталкивалась на ссылку на это древнее решение. Думаю, было бы проще убедить разработчиков IDE реализовать это как маску в редакторе, чем пытаться проникнуть в Oracle.
Супероль
2
Хотя старые рассуждения верны - на практике такие столкновения случаются очень редко.
худенький
14
Я не согласен, что эти столкновения происходят редко. Ориентация на объекты способствует простому именованию. У меня может быть класс Employee из двух разных библиотек, которые делают разные вещи с сотрудником (например).
Андрей
6
@slim « на практике такие столкновения случаются очень редко ». Не ясно, почему эти ситуации будут происходить реже в Java (где вы можете иметь 10.000+ классов) , чем на других языках (где вы обычно имеете меньше классов) , которые делают поддерживают этот «сахар» синтаксис.
Ален Паннетье
21
Абсолютно неверно. Я сталкиваюсь с очень простым сценарием, который, вероятно, очень распространен и где этот синтаксический сахар был бы чрезвычайно полезен. Перевод между связанными, но разными объектными моделями (используются в связанных, но разных продуктах соответственно), чьи классы чаще всего имеют одно и то же имя. Процесс перевода требует, чтобы вы ссылались на оба класса в одном и том же блоке кода. В таком случае (что должно быть очень распространено) Java делает жизнь очень трудной. Только количество просмотров в этом посте должно рассказать вам историю.
hrshi1990
59

Вероятно, стоит отметить, что в Groovy есть эта функция :

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

MyCalendar myCalendar = new MyCalendar()
sfussenegger
источник
15
В Scala это:import com.example.{Calendar => MyCalendar}
Паблиско
24
А в Котлине import com.example.Calendar as MyCalendar.
KevinO
14
В PHP это: используйте com \ example \ Calendar в качестве MyCalendar
matang
19
Очень неприятно видеть, что (по крайней мере) 3 языка на основе JVM (Groovy, Scala & Kotlin) имеют эту функцию, но сама Java все еще не ...
Матиас
2
Как насчет чего-то вроде class MyCalendar extends com.example.Calendar {}? Это не идеальный или красивый, но он должен служить большинству целей, кроме, скажем, рефлексии. Вы можете даже добавить комментарий с комментариями, если это необходимо /* import com.example.Calendar as MyCalendar */.
Брэден Бест
21

Java не позволяет вам сделать это. Вам нужно будет обратиться к одному из классов по его полному имени и импортировать только другой.

sepp2k
источник
8

Сегодня я подал проект JEP в OpenJDK об этой функции наложения имен. Я надеюсь, что они пересмотрят это.

Если вы заинтересованы, вы можете найти черновик JEP здесь: https://gist.github.com/cardil/b29a81efd64a09585076fe00e3d34de7

Крис Сушински
источник
-4

На самом деле можно создать ярлык, чтобы вы могли использовать более короткие имена в своем коде, выполнив что-то вроде этого:

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();
    }
}

Таким образом, вам нужно указать длинное имя только один раз, и вы можете иметь столько специально названных классов, сколько захотите.

Еще одна вещь, которая мне нравится в этом шаблоне, это то, что вы можете назвать реализующий класс так же, как абстрактный базовый класс, и просто поместить его в другое пространство имен. Это не связано с шаблоном импорта / переименования.

4thex
источник
18
Это очень плохое решение. Он полностью не справляется со статикой, может потребовать постоянных обновлений и не помогает с проблемами де / сериализации (такими как десериализация из xml через jaxb).
Инженер-программист