Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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).

like image 692
matrixanomaly Avatar asked Apr 17 '15 19:04

matrixanomaly


People also ask

What is namespace pollution?

Namespace pollution is a lot like pollution in general. It means that something is misplaced. In programming that means that code that should really live in separate namespaces is added to a common namespace (in some cases the global namespace).

Does Java use namespace?

Java packages are namespaces. They allow programmers to create small private areas in which to declare classes. The names of those classes will not collide with identically named classes in different packages.

What is namespace in C# compared to Java?

A namespace is designed for providing a way to keep one set of names separate from another. The class names declared in one namespace does not conflict with the same class names declared in another. In Java, the directory structure should match the package structure, but not required in C#.

Why do we use namespace in C?

The namespace keyword is used to declare a scope that contains a set of related objects. You can use a namespace to organize code elements and to create globally unique types.


2 Answers

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.

like image 69
Marco13 Avatar answered Sep 18 '22 14:09

Marco13


I think Java/C# have a different philosopyh than C++. Let me explain.

When you import something in Java you are only importing it in this part of the code. Let's say you have a class A in package packageA. Furthermore, A imports a class B in package packageB and B imports java.util.LinkedList. In C++, A would include a header-file to use B and in this header-file, you would have an #include for some LinkedList. So the LinkedList would be visible in A. In Java, this is not the case: class A must include java.util.LinkedList on its own to be able to use it. That said, you can still get namespace pollution, but they are more local (typically per-file). This is the reason, why you should avoid the asterisk when using import.

I cannot give a qualified answer for C# since I do not use it, but i think that their philosophy is similar.

like image 43
Turing85 Avatar answered Sep 20 '22 14:09

Turing85