matrixanomaly matrixanomaly - 1 month ago 5
Java Question

Does namespace pollution in Java or C# exist (like in C++)?

I've been puzzled by the concept of how Java and C# handles namespaces.

Firstly, examples of namespace pollution in some programming languages:


  1. using namespace std
    for C++.

    Everyone in the industry frowns upon it, but beginners are still taught to do that when starting programming. Here's a SO question about the advice for handling global namespaces

  2. import math.*
    in Python



When taking a Python class I was told that doing that is not recommended as it pollutes the namespace and firstly allows for access to all methods in the math library without
Math.functionname
but might cause collisions when writing a method with a duplicate name. It also apparently causes more work for the interpreter since it imports all of the functions, even those that aren't used.


  1. open module in Ocaml
    Doing this on the toplevel or in ML files Might cause conflicts in naming as well. Especially if writing a library.

  2. JavaScript namespace pollution



The Question:

Does "namespace pollution" (i.e importing a ton of methods that will potentially cause conflict when writing methods) exist in C# and Java (they are similar in many ways)? Why not?

And of course the related questions that are too similar to ask another question:

-Is it because perhaps we have to explicitly
@Override
things or there's some kind of preventive measure?

-Or it exists, but it's not a thing because it doesn't cause as much havoc as 'using namespace std', and that I'm not aware of it being relatively new to software development out of academic classes?

Example

I find myself
using
a lot of libraries in C# to avoid having to retype the namespaces for a variable, like
XElement


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//the ones above are auto-generated by Visual Studio, too

using System.Xml.Linq;


will avoid me having to do
System.Xml.Linq.XElement
every single time I create an XElement. Much like how we always have to do
std::cout
in C++

or in Java where I commonly see:
import java.util.linkedlist
, even
import java.util.*


Won't these cause namespace pollution if my class is used elsewhere? Or is it because they will only be "polluting" that particular class scope and not in other classes that might import or inherit my class?

I tried searching for an answer but couldn't find one for this, I might be phrasing the search wrongly though.

EDIT 4/20/2015:

As mentioned by @RealSkeptic, it turns out that Java wildcard imports are also discouraged. source

In addition to the accepted answer and answers below, imports in Java and C# are contained within themselves, so even if someone uses a wildcard kind of import that adds unused method names to the namespace, it does not affect the other classes. On a class level, if a collision in names does occur, Java and C# compilers will throw an error citing ambiguous imports and fail to further compile until the issue is resolved (by renaming functions for example).

Answer

As already pointed out by others, the problem of namespace pollution is not as prominent in Java as it is in C++. The main reason why namespace pollution is a problem in C++ (and thus called "pollution" in the first place) is that it may cause errors in other modules. This is explained in more detail in Why is “using namespace std;” considered bad practice?.

(The concerning thing here is that this may not only refer to compile errors: For compile errors, you are forced to do something and to resolve ambiguities. The really concerning thing is that it may cause the code to still compile properly, but afterwards simply call the wrong functions!)


In Java, each import affects only the file in which it is contained. This means that the above mentioned pollution can still occur locally in one file. (One could say: It's only the problem of the author who actually caused the namespace pollution, which is just fair)

Analogously to the case in the above mentioned link: Imagine you are using two libraries, "foo" and "bar". And out of laziness (or lack of knowledge of best practices), you are using the wildcard imports:

import foo.*:
import bar.*:

class MyClass {
    void someMethod() {

        // Assume that this class is from the "foo" librariy, and the
        // fully qualified name of this class is "foo.Example"
        Example e = new Example();
    }
}

Now imagine you upgrade your version of the "bar" library. And the new version contains a class called bar.Example. Then the above code will fail to compile, because the reference to the class Example is ambiguous.

The same problem can, by the way, also appear with static imports. It's a bit more delicate and subtle, and collisions are a bit more likely. That's why they say that you should use static imports very sparingly.


A side note: Of course, these collisions and ambiguities can easily be resolved. You can always use the fully qualified names instead. Most modern Java IDEs offer a functionality to organize/optimize the imports. For example, in Eclipse, you can always press CTRL+Shift+O, which will (depending on the settings in Preferences->Java->Code Style->Organize Imports) replace all wildcard imports with the individual ones.