Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Name clash in java imports

Tags:

java

import

Unless we change the compiler, Java misses the import X as Y syntax, which would be useful in cases like mine: In this very moment I'm working on a project having multiple classes with the same name, but belonging to different packages.

I would like to have something like

import com.very.long.prefix.bar.Foo as BarFoo
import org.other.very.long.prefix.baz.Foo as BazFoo

class X {
    BarFoo a;
    BazFoo b;
    ...
}

Instead I finish in having something like

class X {
    com.very.long.prefix.bar.Foo a;
    org.other.very.long.prefix.baz.Foo b;
    ...
}

Here it seems pretty harmful, but on my specific case I need to use horizontal scrolling in order to browse my source code, and that concours in making worse a program which is already a mess.

In your experience, what is the best practices in this case?

like image 749
Dacav Avatar asked Feb 06 '13 21:02

Dacav


3 Answers

I feel your pain, whichever solution you use, the very fact that there are two classes with the same name is confusing enough.

There are several solutions workarounds:

  1. If this is your code, just rename one of them (or both)
  2. If this is library (which is more likely) import more commonly used class, fully qualify the other one, as Jeff Olson suggested.
  3. Try to avoid having them in the same class in the first place if that is possible.
  4. You could write your own BarFoo and BazFoo which do nothing other than extend their respective Foo classes thus providing them with their own names. You can even define these as inner classes. Example:
private BarFoo extends com.very.long.prefix.bar.Foo{
//nothing, except possibly constructor wrappers
}

private BazFoo extends com.very.long.prefix.bar.Foo{
//nothing, except possibly constructor wrappers
}

class X {
   BarFoo a;
   BazFoo b;
   //...
}

There are some drawbacks, though:

  • You'd have to redefine the constructors
  • It wouldn't be the exact same class, if you need to pass it to a function which is explicitly checking its getClass.

You could solve these drawbacks by wrapping the Foo classes rather than extending them, e.g.:

private BarFoo {
   public com.very.long.prefix.bar.Foo realFoo;
}

private BazFoo extends com.very.long.prefix.bar.Foo{
  public com.very.long.prefix.baz.Foo realFoo;
}

class X {
    BarFoo a;
    BazFoo b;

    //now if you need to pass them
    someMethodThatTakesBazFoo(b.realFoo);
}

Choose the simplest solution and good luck with it!

like image 139
Goran Jovic Avatar answered Nov 18 '22 12:11

Goran Jovic


The best practice is to refactor the code.

Either the classes should not have the same name, because it's normal to use them both in the same classes, and thus choosing the same name for both is not a wise choice. So one of them at least should be renamed.

Or it's not normal to use them both in the same classes because they belong to completely different abstraction levels (like database access code and UI code, for example), and code should be refactored to use each class where it must be used and not elsewhere.

like image 39
JB Nizet Avatar answered Nov 18 '22 11:11

JB Nizet


What I've typically done in these situations is to import the most commonly used Foo in my class, and then fully-qualify the other one:

import com.very.long.prefix.bar.Foo

class X {
    Foo a;
    org.other.very.long.prefix.baz.Foo b;
    ...
}
like image 4
Jeff Olson Avatar answered Nov 18 '22 12:11

Jeff Olson