Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 939
Andy Turner Avatar asked May 31 '18 22:05

Andy Turner


People also ask

Can we create 2 classes with same name?

In fact, you can't create two public classes in a single file, Only one class should be public and it should be the name of the class. If you try to create two public classes in same file the compiler generates a compile time error.

Can we give fully-qualified class name instead of importing that class if yes how do you do that?

If you use fully qualified name then only declared class of this package will be accessible. Now there is no need to import. But you need to use fully qualified name every time when you are accessing the class or interface. It is generally used when two packages have same class name e.g. java.

What is fully qualified name of class?

The fully qualified name of a class is the name of the class prefixed with the package name. For example if class Address is in a package com. mycompany. myproject , then the fully qualified name of class Address is com.

How do you use a fully qualified name?

If you start the filename with "/" indicating the root directory as in "/Users/Name/sample", then on Unix this is a fully qualified file name. So, for example, instead of referring to ./foo/bar/baz.sh in /home/user/quz , which uses a relative pathname, the fully qualified name would be /home/user/quz/foo/bar/baz.sh .


1 Answers

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
like image 176
rgettman Avatar answered Oct 05 '22 13:10

rgettman