Importieren von zwei Klassen mit demselben Namen. Wie verwendet man?

107

Angenommen, ich habe einen Code wie:

import java.util.Date;
import my.own.Date;

class Test{

  public static void main(String [] args){

    // I want to choose my.own.Date here. How?
    ..
    // I want to choose util.Date here. How ?

  }
}

Sollte ich voll qualifizierte Klassennamen sein? Kann ich die Importanweisungen entfernen? Ist ein solches Szenario in der realen Programmierung üblich?

Spiel ist aus
quelle
Keine wirkliche Antwort auf Ihre Frage, aber in C # können Sie einen Alias ​​für jeden Namespace verwenden. Vielleicht
Borjab

Antworten:

153

Sie können die Importanweisungen weglassen und über den gesamten Pfad auf sie verweisen. Z.B:

java.util.Date javaDate = new java.util.Date()
my.own.Date myDate = new my.own.Date();

Aber ich würde sagen, dass die Verwendung von zwei Klassen mit demselben Namen und einer ähnlichen Funktion normalerweise nicht die beste Idee ist, es sei denn, Sie können wirklich klarstellen, welche welche ist.

Ellie P.
quelle
2
Wenn Sie Eclipse verwenden, können Sie den Namen your.own.Datemit Strg + Umschalt + R ändern . Dies ändert sich automatisch überall dort, wo Sie in Ihrem Code darauf verweisen, sowie in der Datei (und dem Dateinamen) Ihrer / own / Date.java. Jede andere IDE hat wahrscheinlich eine ähnliche Funktion.
MatrixFrog
16
Ich stimme der letzten Aussage nicht zu. Wenn Sie Ihre eigene Datumsklasse entwerfen möchten, Dateist dies der perfekte Name. Sie werden es in den meisten Ihrer Codes verwenden. Manchmal müssen Sie jedoch insbesondere anrufen java.util.Date, um Konvertierungen zwischen beiden durchzuführen.
Paradigmatisch
2
@MatrixFrog Die von Ihnen angegebene Funktion in Eclipse wird auch von Netbeans IDE bereitgestellt. Diese Funktion wird als "Refactor" bezeichnet. Ihre Daten waren nicht falsch, aber es ist nicht die Antwort auf die gestellte Frage. Wenn er (Roger) diesen Code entwickelt, weiß er definitiv, dass er den Namen seiner Klasse ändern oder umgestalten kann. Was er fragt, unterscheidet sich von der Antwort, die Sie gegeben haben.
Yatendra Goel
11
@ Yatendra Deshalb habe ich es eher als Kommentar als als Antwort hinzugefügt. Ich ging auf den Punkt ein, den Ellie P. am Ende ihrer Antwort gemacht hatte. Roger weiß das wahrscheinlich, aber der Sinn von SO ist es, anderen Entwicklern zu helfen, nicht nur der Person, die die Frage gestellt hat. Wenn die Leute nichts über die IDE-Funktion wissen, denken sie möglicherweise, dass es nicht möglich ist, Namen von Hand zu wechseln. Daher hielt ich es für nützlich, diese Informationen einzugeben.
MatrixFrog
5
Mein häufigster Namenskonflikt tritt mit org.apache.log4j.Loggerund auf java.util.logging.Logger. Normalerweise habe ich keine Kontrolle über die eine oder andere Seite; Ich mache Legacy-Code-Integration.
Kevinarpe
21

Verwenden Sie den vollständig qualifizierten Namen, anstatt die Klasse zu importieren.

z.B

//import java.util.Date; //delete this
//import my.own.Date;

class Test{

   public static void main(String [] args){

      // I want to choose my.own.Date here. How?
      my.own.Date myDate = new my.own.Date();

      // I want to choose util.Date here. How ?
      java.util.Date javaDate = new java.util.Date();
   }
}
Chii
quelle
6
Best Practice ist es, die am häufigsten verwendete zu importieren, wobei die am wenigsten verwendete mit vollem Klassenpfad verwendet wird
Alpaslan
10

Ja, wenn Sie Klassen mit denselben einfachen Namen importieren, müssen Sie sie mit ihren vollständig qualifizierten Klassennamen referenzieren. Ich würde die import-Anweisungen belassen, da sie anderen Entwicklern einen Eindruck davon vermitteln, was in der Datei enthalten ist, wenn sie damit arbeiten.

java.util.Data date1 = new java.util.Date();
my.own.Date date2 = new my.own.Date();
DC
quelle
7

Eine andere Möglichkeit ist die Unterklasse:

package my.own;

public class FQNDate extends Date {

}

Importieren Sie dann my.own.FQNDate in Pakete mit java.util.Date.

Cheruvim
quelle
Ich mag dies, außer (es ist einfach), aber es geht nicht um das Problem, beispielsweise auf statische Methoden zuzugreifen.
Justin Ohms
Ich mache das die ganze Zeit, wenn ich Hamcrest Matchersund Mockito Matchersin derselben Klasse verwenden möchte . Es scheint mit statischen Methoden zu funktionieren.
Adam Burley
@Kidburla Sie können auch statische Importe verwenden, solange es Ihnen egal ist, welcher Matcher von wo kommt. Ich mache dies oft in Unit-Tests für Matcher und .whens, .thenReturns usw. - entfernt das Mockito.Aufblähen.
CptBartender
Dies ist eine schlechte Praxis. Klassen sollten nicht erweitert werden, es sei denn, einige Funktionen werden gegenüber der ursprünglichen Klasse erweitert.
Partha
3

Wenn Sie eine eigene Datumsklasse haben, sollten Sie diese von der integrierten Datumsklasse unterscheiden. dh warum hast du deine eigenen erstellt? So etwas wie ImmutableDate oder BetterDate oder NanoDate würde sogar MyDate angeben, warum Sie Ihre eigene Datumsklasse haben. In diesem Fall haben sie einen eindeutigen Namen.

Peter Lawrey
quelle
3

Sie können eine davon mit import importieren. Für alle anderen ähnlichen Klassen müssen Sie vollständig qualifizierte Klassennamen angeben. Andernfalls wird ein Kompilierungsfehler angezeigt.

Z.B:

import java.util.Date;

class Test{

  public static void main(String [] args){

    // your own date
    my.own.Date myOwndate ;

    // util.Date
    Date utilDate;
  }
}
Anuraj
quelle
2

Dieses Szenario ist in der realen Programmierung nicht so häufig, aber auch nicht so seltsam. Es kommt manchmal vor, dass zwei Klassen in verschiedenen Paketen denselben Namen haben und wir beide benötigen.

Es ist nicht zwingend erforderlich, dass wenn zwei Klassen denselben Namen haben, beide dieselben Funktionen enthalten und wir nur eine davon auswählen sollten.

Wenn wir beides brauchen, schadet es nicht, das zu benutzen. Und es ist auch keine schlechte Programmieridee.

Wir sollten jedoch vollständig qualifizierte Namen der Klassen (die denselben Namen haben) verwenden, um zu verdeutlichen, auf welche Klasse wir uns ebenfalls beziehen.

:) :)

Yatendra Goel
quelle
2

Ich bin auf dieses Problem gestoßen, wenn ich beispielsweise eine Klasse einer anderen zugeordnet habe (z. B. wenn ich zu einer neuen Gruppe von Klassen gewechselt bin, um Personendaten darzustellen). Zu diesem Zeitpunkt benötigen Sie beide Klassen, da dies der springende Punkt des Codes ist - um eine der anderen zuzuordnen. Und Sie können die Klassen an beiden Orten nicht umbenennen (wieder besteht die Aufgabe darin, zuzuordnen, nicht zu ändern, was jemand anderes getan hat).

Voll qualifiziert ist eine Möglichkeit. Es scheint, dass Sie nicht beide Importanweisungen einschließen können, da Java sich beispielsweise Sorgen darüber macht, welche "Person" gemeint ist.

Randy Wilson
quelle
2

Wenn Sie wirklich denselben Klassennamen aus zwei verschiedenen Paketen verwenden möchten oder müssen, haben Sie zwei Möglichkeiten:

1 Wählen Sie eine aus, die beim Import verwendet werden soll, und verwenden Sie den vollständig qualifizierten Klassennamen der anderen:

import my.own.Date;

class Test{

     public static void main(String[] args){

        // I want to choose my.own.Date here. How?
        //Answer:
        Date ownDate = new Date();

        // I want to choose util.Date here. How ?
        //Answer:
        java.util.Date utilDate = new java.util.Date();

     }
}


2-Verwenden Sie immer den vollständig qualifizierten Klassennamen:

//no Date import
class Test{

  public static void main(String[] args){

    // I want to choose my.own.Date here. How?
    //Answer:
     my.own.Date ownDate = new my.own.Date();
    // I want to choose util.Date here. How ?
    //Answer:
     java.util.Date utilDate = new java.util.Date();

  }
}
manfall19
quelle
0

Ich hatte nur das gleiche Problem, was ich getan habe, ich habe die Bibliotheksreihenfolge nacheinander angeordnet, zum Beispiel gab es java.lang.NullPointerException und javacard.lang.NullPointerException. Ich habe die erste als Standardbibliothek erstellt. Wenn Sie die andere verwenden müssen, können Sie den vollständigen qualifizierten Klassennamen explizit angeben.

Bondhan Novandy
quelle
0

Wenn Sie Klassen mit demselben Namen aufrufen, müssen Sie das Paket, von dem aus die Klasse aufgerufen wird, explizit angeben.

Sie können dies wie folgt tun:

import first.Foo;

public class Main {
    public static void main(String[] args) {
        System.out.println(new Foo());
        System.out.println(new second.Foo());
    }
}



package first;

public class Foo {
    public Foo() {
    }

    @Override
    public String toString() {
        return "Foo{first class}";
    }
}



package second;

public class Foo {
    public Foo() {
    }

    @Override
    public String toString() {
        return "Foo{second class}";
    }
}

Ausgabe:

Foo{first class}
Foo{second class}
Kirilo Lozitsky
quelle
Bitte geben Sie den Code aus dem Screenshot in Ihrer Antwort an.
Thomas Landauer