导入两个具有相同名称的类。怎么处理?


107

说我有一个类似的代码:

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 ?

  }
}

我应该是完全合格的班级名称吗?我可以摆脱导入声明吗?这种情况在现实世界编程中是否常见?


并不是您问题的真正答案,但是在C#中,您可以为任何名称空间使用别名。可能只是语法糖,但确实有帮助:msdn.microsoft.com/en-us/library/7f38zh8x.aspx
borjab 2014年

Answers:


154

您可以忽略导入语句,并使用整个路径引用它们。例如:

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

但是我要说的是,使用两个具有相同名称和类似功能的类通常不是最好的主意,除非您能真正弄清是哪个。


2
如果使用的是Eclipse,则可以更改your.own.Date使用ctrl + shift + R的名称。这将在您在代码中以及您/own/Date.java的文件(和文件名)中引用它的任何地方自动更改它。任何其他IDE可能都具有类似的功能。
MatrixFrog 2010年

16
我不同意上一句话。如果要设计自己的Date类,则Date是完美的名称。您将在大多数代码中使用它。但是,有时您需要java.util.Date特别致电以在两者之间进行转换。
范式

2
@MatrixFrog Netbeans IDE也提供了您在Eclipse中指定的功能。此功能称为“重构”。您的信息没有错,但这不是所提问题的答案。如果他(罗杰)正在开发该代码,那么他肯定会知道他可以更改或重构班级的名称。他的要求与您给出的答案不同。
Yatendra Goel 2010年

11
@Yatendra这就是为什么我将其添加为评论而不是答案的原因。我在扩展Ellie P.在回答结尾时提出的观点。Roger可能知道这一点,但是SO的重点是帮助其他开发人员,而不仅仅是问这个问题的人。如果人们对IDE功能一无所知,他们可能会认为手动切换名称是不可行的,因此我认为输入该信息会很有用。
MatrixFrog 2010年

5
我最常见的名字冲突是org.apache.log4j.Loggerjava.util.logging.Logger。通常,我无法控制任何一侧。我正在做遗留代码集成。
kevinarpe

21

使用完全限定名称而不是导入类。

例如

//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();
   }
}

6
最佳做法是导入最常用的一个,并使用具有完整类路径的最少使用的一个
Alpaslan 2015年

10

是的,当您导入具有相同简单名称的类时,必须使用其完全限定的类名称来引用它们。我将保留import语句,因为它使其他开发人员可以在使用文件时了解文件中的内容。

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

7

另一种方法是将其子类化:

package my.own;

public class FQNDate extends Date {

}

然后在具有java.util.Date的程序包中导入my.own.FQNDate。


我喜欢这样,除了(很简单),但是它不能解决访问静态方法的问题。
贾斯汀·欧姆

当我想在同一班上使用Hamcrest Matchers和Mockito 时,我总是这样做Matchers。它似乎可以使用静态方法。
亚当·伯利

@Kidburla,只要您不在乎哪个匹配器来自哪里,也可以使用静态导入。我经常在匹配器和.whens,.thenReturns等的单元测试中执行此操作-消除了Mockito.膨胀。
CptBartender '16

这是一个坏习惯。除非从原始类扩展了某些功能,否则不应扩展类。
Partha

3

如果您有自己的日期类,则应将其与内置的日期类区分开。即您为什么创建自己的。诸如ImmutableDate或BetterDate或NanoDate之类的东西,甚至MyDate都可以表明您为何拥有自己的日期类。在这种情况下,它们将具有唯一的名称。


3

您可以使用import导入其中之一。对于所有其他类似的类,您需要指定完全限定的类名称。否则会得到编译错误。

例如:

import java.util.Date;

class Test{

  public static void main(String [] args){

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

    // util.Date
    Date utilDate;
  }
}

2

这种情况在现实世界的编程中并不常见,但也不太奇怪。有时候,不同包中的两个类具有相同的名称,而我们都需要它们。

如果两个类具有相同的名称,则这两个类将包含相同的功能不是强制性的,我们应该仅选择其中一个。

如果我们都需要,那么使用它就没有害处。而且这也不是一个坏的编程思想。

但是我们应该使用类的完全限定名称(具有相同的名称),以使我们也清楚地指向哪个类。

:)


2

例如,将一个类映射到另一个类时(例如,切换到一组新的类来表示人员数据时),我遇到了这个问题。那时,您需要两个类,因为这是代码的全部要点-将一个映射到另一个。而且您不能在任何一个地方重命名类(再次,工作是映射,而不是去改变别人所做的事情)。

完全合格是一种方法。看来您实际上不能同时包含两个import语句,例如,因为Java担心使用哪个“ Person”。


2

如果您确实想要或需要使用来自两个不同程序包的相同类名,则有两个选择:

1-选择一个要在导入中使用的名称,并选择另一个用于完全限定的类名称:

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-始终使用完全限定的类名:

//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();

  }
}

0

我只是遇到了同样的问题,我做了什么,我按顺序排列了库的顺序,例如,有java.lang.NullPointerException和javacard.lang.NullPointerException。我将第一个作为默认库,如果需要使用另一个库,则可以显式指定完整的合格类名。


0

调用具有相同名称的类时,必须显式指定从中调用该类的包。

您可以这样做:

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

输出:

Foo{first class}
Foo{second class}

请在答案中包含屏幕截图中的代码。
Thomas Landauer
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.