导入两个名称相同的类。如何处理?

假设我有这样一个代码:

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 ?


}
}

我应该是完全限定类名吗?我可以删除导入报表吗?这种情况在现实世界的编程中很常见吗?

148076 次浏览

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

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

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

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

例如:。

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

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

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

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

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

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

但是,我们应该使用完全限定的类名(有相同的名称) ,以便明确我们也引用哪个类。

:)

如果您有自己的日期类,则应该将其与内置的 Date 类区分开来。也就是说,你为什么要创造自己的。比如 ImmutableDate、 BetterDate 或 NanoDate,甚至 MyDate 都会告诉你为什么你有自己的日期类。在这种情况下,它们将有一个唯一的名称。

另一种方法是对它进行子类化:

package my.own;


public class FQNDate extends Date {


}

然后在包含 java.util. Date 的包中导入 my.own. FQNDate。

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

完全合格是一种方法。看起来你实际上不能同时包含两个 import 语句,因为 Java 会担心“ Person”是什么意思。

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

例如:

import java.util.Date;


class Test{


public static void main(String [] args){


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


// util.Date
Date utilDate;
}
}

我也遇到了同样的问题,我按顺序排列了库的顺序,比如 java.lang。NullPointerException 和 javacard.lang。NullPointerException.我将第一个作为默认库,如果需要使用另一个,可以显式指定完整的限定类名。

如果您确实希望或需要从两个不同的包中使用相同的类名,您有两个选择:

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


}
}

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

你可以这样做:

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}

如果必须在同一个文件中使用两个具有相同名称但包不同的类,那么除了对两个类中的至少一个使用完全限定名之外,没有其他选择。我越来越想知道,在这种情况下,我们是否不应该一直使用完全限定名,这样就更清楚哪个类是哪个类,但是由于增加了冗长性,这会使代码更难解析。不幸的是,越来越多的程序员通过复制所有的数据对象来实现这一点: 在 GRPC 的情况下,一个由 Protoc 生成的副本,一个用于 JSON 序列化的副本,一个用于内部逻辑的副本,一个用于 Hibernate 的副本,等等,没有任何自动化的方法来映射一个到另一个,到处都是普通的旧代码复制。IDE 设计得不是很好,只能显示 com.abc. myproject... 。而不是在尝试使用代码完成时使用完全限定名。不幸的是,Java 本身没有提供好的解决方案,IDE 不得不使用自动完成或自动导入。这里我们需要 C # 、 Python 和 Javascript 提供的别名。