0

I came across: import static java.lang.Float.*;, note the static (actually it was import static java.lang.Math.* but that aside). I had never seen that before and thought it was very usefull, Float.valueOf("1.234f"); becomes valueOf("1.234f").

But when i added import static java.lang.Integer.*; also, i got an error message: "reference to valueOf is ambiguous" because both these classes have that (static) method.

Is there is no way around that? I can use this only a limited of times before its ambiguous somewhere?

On a sidenote:

Has this situation the same background as why we can only extend one class, because if we could extend two classes, for all the static fields etc, the naming could cause the same problems?

WonderWorld
  • 956
  • 1
  • 8
  • 18
  • 5
    Don't import them statically. – Malik Brahimi Mar 30 '15 at 22:53
  • You can static import as much as you want, but if a reference is ambiguous you'll have to explicitly clarify which method you're referencing. – Louis Wasserman Mar 30 '15 at 22:53
  • @LouisWasserman Thats what i thought. And the sidenote? – WonderWorld Mar 30 '15 at 22:54
  • 2
    *"Is there is no way around that?"* Sure it is: **never** use wildcard imports. And then import only that stuff that you _really_ need. – Tom Mar 30 '15 at 22:54
  • @Tom You mean `import static java.lang.Float.valueOf;` as "*only that stuff that you **really** need*" – WonderWorld Mar 30 '15 at 22:57
  • The "sidenote" should be a separate question, since it's pretty different. You should google for C++ multiple inheritance to see the complexities it introduces, especially with regard to fields (trying to avoid them is the main reason Java doesn't let you extend multiple classes). – yshavit Mar 30 '15 at 23:00
  • @Tom *I can't see anything wrong with wildcard imports.* It's a common formatting patting in Intellij to replace 5+ static imports with a single * import. I'm fairly confident that every post-2005 compiler will optimise it, so it's really only a matter of convenience while typing your code. – Jan Groth Mar 30 '15 at 23:01
  • @yshavit it's not one of the reasons? – WonderWorld Mar 30 '15 at 23:01
  • @jangroth Imo thats a stupid default setting in IntelliJ and one of the first things I change if I install it. The first problem with wildcard imports can you see in this question. Another one is, that it hides which class is really used in the program, or (from the over direction) there a used class comes from. You then can't tell if this class comes from the same package (so there is no import for that) or it is included in one wildcard imports. But that might not be a big problem if you always use an IDE to view code, even during a code review. – Tom Mar 30 '15 at 23:11
  • @jangroth There's nothing to optimize: the bytecode looks exactly the same with or without the imports (it references the full class name either way). Same with non-static imports, too. They're purely for convenience and clarity of code. – yshavit Mar 30 '15 at 23:32
  • @Tom - let's not take that too far, but the typical wildcard static import scenario I see are enums, with very little danger of getting confused. Also I'm not too fussed about it, I guess you using the word *never* made me suddenly feel *very* bad about all the code I had written over the last decade... ;) – Jan Groth Mar 30 '15 at 23:34
  • @jangroth then this was bad code... just kidding :-P. I also used wildcard imports until several months ago, but I changed my mind on that point. So I won't use it anymore and argue against it. So don't feel bad, I have no intention to mock someones (existing) code ;-). – Tom Mar 31 '15 at 07:15

4 Answers4

5

As you note, you don't need to reference Float to access its static methods when you import it statically. But because both Float.valueOf(String string) and Integer.valueOf(String string) are available, how could the compiler know if you mean you want a Float value or an Integer value when you call valueOf(String string)?

The compiler only matches the method name and signature: a "valueOf" and a single string argument. It doesn't see that you have a decimal point and an f in your string: that's what valueOf does.

To resolve the ambiguity, call either Float.valueOf("1.234f") or Integer.valueOf("1234").

Joseph Nields
  • 5,527
  • 2
  • 32
  • 48
2

Both classes are already imported for you, so just call the ambiguous method explicitly:

Float.valueOf(arg); // or Integer.valueOf(arg);
Malik Brahimi
  • 16,341
  • 7
  • 39
  • 70
0

Regarding the "side note": IMHO it would have been better to ask your side note in a new question, but to answer it: No, this is a very different thing. Java decided to not allow multiple inheritance to avoid the diamond problem.

  • C++ does allow it but it's one of the reasons why that language is considered complicated.
  • Scala does allow it too (called traits) and resolves the diamond problem by inheritance order to resolve issues. Read this good post explaining it.
Maze
  • 726
  • 6
  • 9
0

This is really no different than having 2 different classes with the same name (in different packages). Only 1 can be imported and the other must be referenced using the fully qualified name.

Brett Okken
  • 6,210
  • 1
  • 19
  • 25