Java中的名称空间包相对标识符路径
导言
从C++中移出的一个最大区别是范围的差异:在C++中,每个标识符都与当前的范围(^ {< CD1>}或^ {CD2>})相对应,并且可以在开始时用范围解析操作符{{CD3}}编写绝对路径。p>
然而,在Java中,如果不将标识符导入当前作用域或写入其完整路径,我无法找到从其他包访问标识符的方法
如果我有几个同名的类,那么在C++中,我会把它们定义为模块1::FoO和Meule2::FoO,这是不可能的,只要我想保存我的心智,因为^ {CD4}}太长,我的口味太长了。< /p>密码
这里是一个例子,用于访问来自java和C++的类^ {CD5>}(没有^ {CD6>}或^ {< CD7>})
Tools/Useless/Foo.hpp
namespace Tools {
namespace Useless {
class Foo {
};
}
}
Tools/Bar.hpp
namespace Tools {
...
// Use Foo with a relative identifier
Useless::Foo foo;
// Use Foo with an absolute identifier.
::Tools::Useless::Foo bar;
...
}
这就是它在Java中的外观:
com/company/project/Tools/Useless/Foo.java
:
package com.company.project.Tools.Useless;
public class Foo { }
com/company/project/Tools/Bar.java
...
// Use Foo with a relative identifier
???
// Use Foo with an absolute identifier.
com.company.project.Tools.Useless.Foo foo;
...
问题
- 有没有一种方法可以从包
Tools.Useless
访问Foo
而不指定Tools.Useless
完整的包名(并导入它;因为导入它会将它绑定到当前范围)李> - 我做得对吗?我应该如何使用几个同名的类?我应该避免这样做,还是直接用“package.*”导入它们来绕过它李>
解决方案
- 使用更多的包描述性类名(例如
ToolsUselessFoo
,而不仅仅是Foo
)李> - 用
import path.to.module.*
而不是import path.to.module.Foo
导入所有内容,然后访问Foo
所需的包以解决任何歧义。问题是,有时包名有一个含义(例如Tools.Useless.Foo
和Tools.Useful.Foo
)李>
# 1 楼答案
Java包不是嵌套的。虽然它们的名字可能有共同的前缀,但这在Java编程语言中没有任何意义
此外,当存储是文件系统时,它们的类文件存储在嵌套目录中,这一事实没有其他意义。当类存储在jar文件中时,它们的条目名与它们的限定名匹配,而实际上根本不形成目录(尽管许多工具喜欢将它们呈现为一个层次结构,以模拟文件系统)
所以包
com.company.project.tools.useless
和com.company.project.tools
根本没有关系。虽然我们人类倾向于以这样的方式组织代码,这里可以假设语义关系(这是一件好事),但在技术层面上没有。与其他两个包相比,它们之间没有相对寻址,也没有额外的访问权限。事实上,这两个包可能是两个不同模块(从Java 9开始)的一部分,与其他两个名称不太相似的包相比,访问权限更少使用另一个包中的类的标准方法是使用
import com.company.project.Tools.Useless.Foo;
,然后在类中使用Foo
目前还不清楚,您看到的问题是什么,即“因为导入它会将其绑定到当前范围”应该是什么意思。仅仅存在
import
语句对代码没有影响。它告诉编译器的只是,如果范围内没有其他Foo
,如何解析简单名称Foo
的出现换句话说,局部作用域仍然具有优先权,甚至包括继承的成员。此外,在变量和类型可能出现的地方,变量具有优先权。例如,对于
Foo.bar()
的出现,一个名为Foo
的变量将具有优先级,一个局部变量优先于同一类型内的成员变量,一个外部类或继承类。否则,将使用成员类型、外部类型或继承的成员类型。只有当它们都不存在时,import
语句才会用于解析Foo
不用说,您应该避免使用太多相同简单名称的项目,这样您就必须考虑解决过程的细节。这就是为什么命名约定建议变量名以小写字母开头,类名以大写字母开头
是的,避免给类起相同的简单名称。一旦必须在同一个编译单元中处理这两个类,就无法在整个编译单元中访问其中一个具有其(完整的)限定名的类。(在导入中使用
*
对这种情况没有任何帮助)如前所述,“完全”一词在Java中已经过时,因为限定名总是完整的