Change Name of Import in Java, or import two classes with the same name
Asked Answered
O

9

543

In Python you can do a:

from a import b as c

How would you do this in Java, as I have two imports that are clashing.

Overhead answered 15/3, 2010 at 14:39 Comment(0)
M
697

There is no import aliasing mechanism in Java. You cannot import two classes with the same name and use both of them unqualified.

Import one class and use the fully qualified name for the other one, i.e.

import com.text.Formatter;

private Formatter textFormatter;
private com.json.Formatter jsonFormatter;
Mcfall answered 15/3, 2010 at 14:41 Comment(13)
That's the right answer and to that I'd only add what you have implied: no, there is no such aliasing syntax in Java.Perithecium
Is this still a limitation in Java 8?Varicocele
@Varicocele Nope, unfortunately no import aliasing have been added in Java8Albertinaalbertine
Yeah I agree with your comment linuxdan... Java has gone the way of the dinosaur in terms of updates to its syntax.Lyric
And how would you resolve that particular case if you were to design a language?Mcfall
@Mcfall The way python does: import [fully-qualified-name] as [ident]. The “as” keyword doesn’t seem to fit in Java as well, an alternative is approximately what C# uses: import [ident] = [fully-qualified-name].Ringe
Yes, that was what the OP suggested. But I don't think it makes such a big difference :)Mcfall
It's better if you use fully qualified names for both classes when there are clashes like this. There is usually no good reason to prefer importing one over the other (maybe, if one is used 99.999% of the time, and the other one just once, you might prefer the import approach, but even then it's confusing).Rinse
If my language A has a functionality that foreign language B misses: wow, how A is superior. If foreign language B has a functionality that A misses: meh, I don't get it why that's so important anyway... (yes, I'm talking about you, Blub Paradox).Kai
@Mcfall C# handles it like this: using MyAlias = Full.Namespace.Path.To.Some.Class;Embrace
Boo java. +1 for answer.Adulation
I agree with @EngineerDollery, prioritizing one import over another creates ambiguity and confusion over what type "Formatter" refers to. I would use the fully-qualified names for each and abstract them into a third class. Call it something like TextAndJSONFormatter.Artamas
Instead in kotlin its implemented, and I will switch my spring project to kotlin for this and huge of another reasonsSever
T
109

As the other answers already stated, Java does not provide this feature.

Implementation of this feature has been requested multiple times, e.g. as JDK-4194542: class name aliasing or JDK-4214789: Extend import to allow renaming of imported type.

From the comments:

This is not an unreasonable request, though hardly essential. The occasional use of fully qualified names is not an undue burden (unless the library really reuses the same simple names right and left, which is bad style).

In any event, it doesn't pass the bar of price/performance for a language change.

So I guess we will not see this feature in Java anytime soon :-P

Trichinize answered 12/9, 2015 at 10:3 Comment(21)
wow! you weren't kidding about "not (...) anytime soon", I see that the feature request was dismissed as pointless sugar as far back as 1998! And every attempt to re-open the discussion during these past 18years have stranded on a reference to that ancient decision. I guess it would be easier to convince IDE-developers to implement this as a mask in the editor than to try to knock sense into Oracle.Dowdell
The old reasoning is correct though -- in practice these clashes very seldom occur.Fryd
I don't agree that these clashes rarely occur. Object orientation favors simple naming. I can have a class Employee from two different libraries that do separate things with an employee (for example).Gudrin
@Fryd "in practice these clashes very seldom occur". It is not clear to me why these situations would occur less frequently in java (where you can have 10.000+ classes) than in other languages (where you usually have less classes) which do support this "sugar" syntax.Arezzo
@AlainPannetier all I can say is, I've only experienced these clashes a handful of times in 15 years of Java programming. Yes, you can have 10,000+ classes in a project. But any given class should only need to reference a few.Fryd
Absolutely incorrect. I'm facing a very simple scenario which is probably very common and where this syntactic sugar would be extremely helpful. Translation between related, but distinct object models (used in related but different products respectively) whose classes most of the time share the same name. The translation process requires you to refer to both classes in the same code block. In such a case (which must be very common), Java makes life very difficult. Just the number of views on this post should tell you the story.Gerta
And we have not yet considered static imports regarding the chance of clashing. Indeed static imports are not necessary as they can be simplified by qualifying with the simple declaring class name, but it's still inconvenient (depending on why you want to use static import in the first place).Pazit
@Fryd - It's possible your assertion is true in the domains that you've worked in. I've also worked in a number of domains where I had no use for the ability to alias. However, in some domains, such as model-mapping/translation between models, as hrishirc mentions it is very common. As the service API's become more and more prevalent, model mapping will be an even larger part of our world. It is short-sighted to discard a legitimate feature request just because a person may not have experienced the need themselves. Language core versus business system integration are very different beasts.Chili
All the above, and that, maybe, just maybe, you don't want to have to type "com.company.library.project.component.class.fieldName" 50 times.Branum
"In any event, it doesn't pass the bar of price/performance for a language change." - This pretty much summarizes why Java is so poorly designed. Scala for instance solved this LONG ago.Tipi
I don't think the main problem is the difficulty of implementation. I can't find the link at the moment, but I remember to have read somewhere about the problems of language changes (especially syntax changes) from one of the Java architects. They where similar in tone with the ones of Eric Lippert, one of the C# designers: "… just being a good feature is not enough" or this article.Trichinize
It's a constant burden for me that i encounter in every project and throughout my own common libraries. You have a 'Controller' that is in both server and client packages yet you are forced to name then ClientController and ServerController. I end up prepending the package name to every class so I end up with ControlButton, ControlTextBox, ControlListBox etc.. It's the only way around this very annoying problem.Chengteh
If "these clashes very seldom occur" then this question wouldn't have so many upvotes from people wondering how to do it.Suiter
I don't get the "price/performance for a language". There's a price, ok, but performance-wise? Why should it be so? Are the other JVM-targeting languages performance-impaired because they implement this aliasing? Even if Java is the exception rather than the norm! What about having to import 2 Article classes that could be renamed as, say, MagazineArticle and MaterialGood? But I don't even care about clashes: I want it for clarity or brevity. I'm not forced to use article for an instance of Article, so I shouldn't be forced to refer to that particular Article class with Article.Trespass
@ShinTakezou, I guess what the author wanted to express with "performance" is not (only) "speed" but rather "what you get from this language change". In other words: This changes impact on everyday use of the language is too small compared to its "cost" (e.g. increased complication of specification and learning effort for (new) users of the language, cost of implementation and future maintenance).Trichinize
@Trichinize Learning efforts are 0: old-style Java guys can continue using imports the way they are used to: no one is forcing them to use any new backward-compatible feature of whatever language. The fact that other languages, even JVM-targeting ones, have the feature, what does it says about "cost of implementation and future maintenance"? Are you saying the other languages are plagued by "cost problems" because of that feature? Or that Java implementation is far more complicated, or delicate, and its maintainers don't take the risk lest they screw up? It's nonsense.Trespass
I encounter this if I use two different utility libraries e.g. io.vavr.collection.List and java.util.List. It's a shame Java does not have it yet.Nephralgia
The use of the java xml binding library would benefit from renaming. I have a lot of XML "ObjectFactory"s in the code base. So ... how to know which one it is looking at the source code? Oh... and Java does not allow package import. That would solve some of the issues.Sectary
I am working on adding another API version to a web service, and I have ...v1.Address and ...v2.Address etc for dozens of classes, and probably more versions in the future. I suppose I could call them AddressV1 and AddressV2 etc but that involves a lot of search/replace operations.Seringapatam
Dont agree, one of my classes uses 2 imports with the same class name, i have so many lines with the fully qualified class name, is becoming horrible to look at.Exocentric
I think the change to use Aliases is essential so Java developers might want to look at it. Im maintaining old code and i have to change every line to point to "import java.util.Base64.Encoder" from the old "import sun.misc.BASE64Encoder;" There will always be new things so an alias will be a one line changeCapacitate
R
94

It's probably worth noting that Groovy has this feature:

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

MyCalendar myCalendar = new MyCalendar()
Rowboat answered 6/2, 2015 at 9:6 Comment(10)
In Scala it's: import com.example.{Calendar => MyCalendar}Moorfowl
And in Kotlin: import com.example.Calendar as MyCalendar.Erving
In PHP it's : use com\example\Calendar as MyCalendarCharmian
In ES6 it is `import { Calender as MyCalendar } from "com/example/calendar"Earflap
It's quite annoying to see that (at least) 3 JVM-based languages (Groovy, Scala & Kotlin) have this feature but Java itself still doesn't ...Sheilahshekel
What about something like class MyCalendar extends com.example.Calendar {}? It's not ideal or pretty, but it should serve most purposes short of, say, reflection. You could even prepend it with a comment if necessary, like /* import com.example.Calendar as MyCalendar */.Artamas
this is damn Java!Euhemerus
in Python it;s: from com.example import Calendar as MyCalendarBondy
In C# it's: using MyCalendar = com.example.Calendar;Insulin
And in Haskell: import qualified Data.Map as M. If you leave out the word qualified you can prefix those imports with M. if you like, and if you leave off the M. it'll still work as long as the name is unambiguous given your other imports and the definitions in that module.Mumbletypeg
O
26

Java doesn't allow you to do that. You'll need to refer to one of the classes by its fully qualified name and only import the other one.

Ortensia answered 15/3, 2010 at 14:41 Comment(0)
C
24

Today I filed a JEP draft to OpenJDK about this aliasing feature. I hope they will reconsider it.

If you are interested, you can find a JEP draft here: https://gist.github.com/cardil/b29a81efd64a09585076fe00e3d34de7

Coordinate answered 7/8, 2019 at 13:8 Comment(4)
It's been more than 2years now, what's the status of your draft? Can't find it in the JEP listingErena
Yeah, I did send that Draft to an email address as described in JEP 1, but I didn't receive any feedback. That's why I posted it to gist instead. Maybe it's a good idea to try submitting it once again. It looks like the process might have changed since then.Bannerman
@ChrisSuszyński any update on this? With jaav new approach to language features I'm really looking forward to this...Prior
it was dismissed 24 years ago and still is. I have no hopes. Well, I mostly write Kotlin these daysStarlin
V
14

It's ridiculous that java doesn't have this yet. Scala has it

import com.text.Formatter
import com.json.{Formatter => JsonFormatter}

val Formatter textFormatter;
val JsonFormatter jsonFormatter;
Voracious answered 21/8, 2020 at 23:43 Comment(1)
python has it tooOutward
S
6

Unless there are problems with non-default constructors you can always do this (while we all wait for the Java language specification to catch up):

public class YaddaYadda
{
    private static class ZU extends eu.zrbj.util.ZrbjUtil_3_0 { }

    public void foo (String s)
    {
        if (ZU.isNullOrEmpty(s))
        {
            // ...

For project-wide use the 'import' class can go into a separate class file, giving a single point of definition for the import.

This is a lifesaver especially with regard to 'library' classes, meaning collections of static utility functions. For one thing it gives you the ability to version these beasts - as shown in the example - without major inconvenience for the user.

Sampan answered 22/6, 2021 at 18:34 Comment(0)
C
0

Although Ballerina is a language which can be run on JVM, it also offers import aliasing.

import ballerina/jballerina.java.arrays as jarrays;
Calisa answered 13/8, 2023 at 13:19 Comment(0)
G
-5

Actually it is possible to create a shortcut so you can use shorter names in your code by doing something like this:

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

In that way you only need to specify the long name once, and you can have as many specially named classes you want.

Another thing I like about this pattern is that you can name the implementing class the same as the abstract base class, and just place it in a different namespace. That is unrelated to the import/renaming pattern though.

Geniality answered 22/1, 2016 at 1:49 Comment(3)
This is a very poor solution. It completely fails to deal with statics, may require constant updates, and doesn't help with de/serialisation problems (such as deserialising from xml through jaxb).Rinse
The self-annointed 'Software Engineer' fails to realise two things. (1) Some of the problems he/she/it mentions apply equally to a hypothetical language-level solution. (2) A solution that does not work for some special cases may still work well for many other cases, in any case enough to be of use for the readers of this forum. Based on almost four decades of programming experience (three of which as a professional developer) I would call 4thex's solution a win. Not to forget that it is the only solution so far in the whole topic, after more than 10 years!Sampan
IMHO extending classes to work around the lack of import aliases is witty, but in the long term it seems to me that people will look at the code and say "wtf? what is this for?" And this is a best case scenario, where you don't need to worry about constructors and whatnot.Ivyiwis

© 2022 - 2024 — McMap. All rights reserved.