How to refer to a class when both simple and fully-qualified names clash

Andy Turner :

Consider the following pathological example:

class Ideone {
  static class ArrayList<T> {
    ArrayList() {
      System.out.println("!!");
    }
  }

  static class java {
    static class util {
      static class ArrayList<T> {
        ArrayList() {
          System.out.println("Here");
        }
      }
    }
  }

  public static void main(String[] args) {
    new ArrayList<>();
    new java.util.ArrayList<>();
    // Can I refer to the "usual" java.util.ArrayList?
  }
}

The two instances created in the constructor are of the nested classes.

But how might I refer to the java.util.ArrayList that we all know and love in the same class? We can't import it, and we can't use the fully-qualified name, as the nested class symbols would be used instead.

What can we do in this case? (Other than the obvious - stop using such wantonly evil names for the nested classes).

rgettman :

You can no longer directly reference java.util.ArrayList if you've done the 2 things you've done:

  1. Hide the simple name ArrayList with a static nested class in scope.
  2. Hide the fully qualified name java.util.ArrayList with a class ArrayList nested within class util, nested within nested class java.

You can't even "split" the import in an attempt to use a "partially qualified" import.

import java.*;

...

// This doesn't work!
new util.ArrayList<>();

You can import java.*;, but that is worthless; no classes are defined in the java package directly.

However, you can reference the class java.util.ArrayList indirectly because it's not final. Outside the scope of the class Ideone, declare a subclass with a different name.

class AnArrayList<T> extends java.util.ArrayList<T> {}

Then you can refer to that class and program to the interface:

List<Integer> al = new AnArrayList<>();  // won't print !! or Here

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=36391&siteId=1