Importer deux classes avec le même nom. Comment gérer?

107

Disons que j'ai un code comme:

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 ?

  }
}

Dois-je être des noms de classe qualifiés complets? Puis-je me débarrasser des instructions d'importation? Un tel scénario est-il courant dans la programmation du monde réel?

jeu terminé
la source
Ce n'est pas vraiment une réponse à votre question, mais en C #, vous pouvez utiliser un alias pour n'importe quel espace de noms. Ce n'est peut-être que du sucre syntaxique, mais c'est vraiment utile: msdn.microsoft.com/en-us/library/7f38zh8x.aspx
borjab

Réponses:

154

Vous pouvez omettre les instructions d'importation et y faire référence en utilisant le chemin complet. Par exemple:

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

Mais je dirais que l'utilisation de deux classes avec le même nom et une fonction similaire n'est généralement pas la meilleure idée à moins que vous ne puissiez vraiment clarifier laquelle est laquelle.

Ellie P.
la source
2
Si vous utilisez Eclipse, vous pouvez changer le nom de l' your.own.Dateutilisation de ctrl + shift + R. Cela le changera automatiquement partout où vous y ferez référence dans votre code, ainsi que dans le fichier (et le nom de fichier) votre / propre / Date.java. Tout autre IDE a probablement une fonctionnalité similaire.
MatrixFrog
16
Je ne suis pas d'accord avec la dernière déclaration. Si vous souhaitez concevoir votre propre classe Date, le Dateest le nom parfait. Vous l'utiliserez dans la plupart de votre code. Cependant, vous devrez parfois appeler le java.util.Datenotamment pour effectuer des conversions entre les deux.
paradigmatique du
2
@MatrixFrog La fonctionnalité d'Eclipse que vous avez spécifiée est également fournie par Netbeans IDE. Cette fonctionnalité est connue sous le nom de "Refactor". Vos informations n'étaient pas fausses mais ce n'est pas la réponse à la question posée. S'il (Roger) développe ce code, alors il sait certainement qu'il peut changer ou refactoriser le nom de sa classe. Ce qu'il demande est différent de la réponse que vous avez donnée.
Yatendra Goel
11
@Yatendra C'est pourquoi je l'ai ajouté comme commentaire plutôt que comme réponse. J'étendais sur l'argument d'Ellie P. à la fin de sa réponse. Roger le sait probablement, mais le but de SO est d'aider d'autres développeurs, pas seulement la personne qui a posé la question. Si les gens ne connaissent pas la fonctionnalité IDE, ils pourraient penser qu'il est impossible de changer de nom à la main, alors j'ai pensé qu'il serait utile d'ajouter cette information.
MatrixFrog
5
Mon conflit de nom le plus fréquent se produit avec org.apache.log4j.Loggeret java.util.logging.Logger. Habituellement, je n'ai aucun contrôle sur un côté ou sur l'autre; Je fais l'intégration de code hérité.
kevinarpe
21

utilisez le nom complet au lieu d'importer la classe.

par exemple

//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
la source
6
La meilleure pratique consiste à importer le plus utilisé, en utilisant le moins utilisé avec le chemin de classe complet
Alpaslan
10

Oui, lorsque vous importez des classes avec les mêmes noms simples, vous devez y faire référence par leurs noms de classe complets. Je laisserais les instructions d'importation, car cela donne aux autres développeurs une idée de ce qui se trouve dans le fichier lorsqu'ils travaillent avec.

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

Une autre façon de le faire est de le sous-classer:

package my.own;

public class FQNDate extends Date {

}

Et puis importez my.own.FQNDate dans les packages contenant java.util.Date.

Cheruvim
la source
J'aime cela sauf (c'est simple) mais cela ne résout pas le problème, par exemple, d'accéder aux méthodes statiques.
Justin Ohms
Je fais ça tout le temps quand je veux utiliser Hamcrest Matcherset Mockito Matchersdans la même classe. Cela semble fonctionner avec des méthodes statiques.
Adam Burley
@Kidburla, vous pouvez également utiliser des importations statiques tant que vous ne vous souciez pas de quel matcher vient d'où. Je fais souvent cela dans les tests unitaires pour les matchers et .whens, .thenReturns etc. - supprime le Mockito.gonflement.
CptBartender
C'est une mauvaise pratique. Les classes ne doivent pas être étendues à moins que certaines fonctionnalités ne soient étendues à partir de la classe d'origine.
Partha le
3

Si vous avez votre propre classe de date, vous devez la distinguer de la classe Date intégrée. c'est-à-dire pourquoi avez-vous créé le vôtre. Quelque chose comme ImmutableDate ou BetterDate ou NanoDate, même MyDate indiquerait pourquoi vous avez votre propre classe de date. Dans ce cas, ils auront un nom unique.

Peter Lawrey
la source
3

Vous pouvez en importer un à l'aide de l'importation. Pour toutes les autres classes similaires, vous devez spécifier des noms de classe complets. Sinon, vous obtiendrez une erreur de compilation.

Par exemple:

import java.util.Date;

class Test{

  public static void main(String [] args){

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

    // util.Date
    Date utilDate;
  }
}
Anuraj
la source
2

Ce scénario n'est pas si courant dans la programmation du monde réel, mais pas si étrange aussi. Il arrive parfois que deux classes dans des packages différents aient le même nom et que nous ayons besoin des deux.

Il n'est pas obligatoire que si deux classes ont le même nom, alors les deux contiendront les mêmes fonctionnalités et nous ne devrions en choisir qu'une.

Si nous avons besoin des deux, il n'y a aucun mal à l'utiliser. Et ce n'est pas non plus une mauvaise idée de programmation.

Mais nous devrions utiliser des noms complets des classes (qui ont le même nom) afin de préciser à quelle classe nous nous référons également.

:)

Yatendra Goel
la source
2

Je rencontre ce problème lorsque, par exemple, mappe une classe à une autre (comme lors du passage à un nouvel ensemble de classes pour représenter des données de personne). À ce stade, vous avez besoin des deux classes car c'est tout le but du code - pour mapper l'une à l'autre. Et vous ne pouvez pas renommer les classes dans les deux endroits (encore une fois, le travail est de mapper, pas d'aller changer ce que quelqu'un d'autre a fait).

Pleinement qualifié est un moyen. Il semble que vous ne pouvez pas réellement inclure les deux instructions d'importation, car Java s'inquiète de savoir de quelle "personne" il s'agit, par exemple.

Randy Wilson
la source
2

Si vous voulez vraiment ou avez besoin d'utiliser le même nom de classe à partir de deux packages différents, vous avez deux options:

1-en choisir un à utiliser dans l'importation et utiliser le nom de classe complet de l'autre:

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-utilisez toujours le nom de classe complet:

//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
la source
0

J'ai juste eu le même problème, ce que j'ai fait, j'ai arrangé l'ordre des bibliothèques dans l'ordre, par exemple il y avait java.lang.NullPointerException et javacard.lang.NullPointerException. J'ai créé la première comme bibliothèque par défaut et si vous deviez utiliser l'autre, vous pouvez spécifier explicitement le nom complet de la classe qualifiée.

Bondhan Novandy
la source
0

Lorsque vous appelez des classes avec les mêmes noms, vous devez spécifier explicitement le package à partir duquel la classe est appelée.

Vous pouvez faire comme ceci:

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}";
    }
}

Production:

Foo{first class}
Foo{second class}
Kirilo Lozitsky
la source
Veuillez inclure le code de la capture d'écran dans votre réponse.
Thomas Landauer