java - Java 中包相对标识符路径

标签 java namespaces package project

简介

从 C++ 迁移过来,最大的区别之一是作用域的不同:在 C++ 中,每个标识符都相对于当前作用域(classnamespace),您可以在开头编写一个带有范围解析运算符 :: 的绝对路径。

但是,在 Java 中,我无法找到一种方法来访问其他包中的标识符,而不将其导入到当前作用域或写入其完整路径。

如果我有几个同名的类,这可能会是一个问题(然后,在 C++ 中,我会将它们称为 Module1::Foo 和 Module2::Foo,只要我愿意,这在 Java 中是不可能的)保存我的理智,因为 com.company.project.module1.Foo 对我来说太长了)。

代码!

以下是从 Java 和 C++ 访问类 Tools.Useless.Foo 的示例(没有 importusing)

工具/Useless/Foo.hpp:

namespace Tools {
namespace Useless {
class Foo {         
};
}
}

工具/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;
...

问题

  1. 有没有办法从包 Tools.Useless 访问 Foo 而不指定 Tools.Useless 完整包名称(并导入它;因为导入它会将其绑定(bind)到当前作用域)?
  2. 我做得对吗?我应该如何使用几个同名的类?我应该避免这种情况,还是直接用“package.*”导入它们来绕过它?

解决方案

  1. 使用更多包描述性类名(例如 ToolsUselessFoo 而不仅仅是 Foo)。
  2. 使用 import path.to.module.* 而不是 import path.to.module.Foo 导入所有内容,然后访问 Foo解决任何歧义所需的包。问题是有时包名称具有含义(例如 Tools.Useless.FooTools.Useful.Foo)。

最佳答案

Java 包不嵌套。虽然它们的名称可能具有共同的前缀,但这在 Java 编程语言中没有任何意义。

此外,当存储是文件系统时,它们的类文件存储在嵌套目录中,这一事实没有其他意义。当类存储在 jar 文件中时,它们的存储条目名称与其限定名称相匹配,而根本不实际形成目录(尽管很多工具喜欢将它们呈现为分层结构以模仿文件系统)。

所以包com.company.project.tools.uselesscom.company.project.tools根本没有关系。虽然我们人类倾向于以这样的方式组织代码,但这里可以假设语义关系(这是一件好事),但在技术层面上却没有。与任何其他两个包相比,它们之间没有相对寻址,也没有额外的访问权限。事实上,这两个包都可以是两个不同模块的一部分(从 Java 9 开始),与其他两个名称不太相似的包相比,访问权限甚至更少。

使用另一个包中的类的标准方法是使用 import com.company.project.Tools.Useless.Foo;,然后在其中使用 Foo类(class)。

目前还不清楚您看到了什么问题,即“自从导入它会将其绑定(bind)到当前作用域”应该意味着什么。 import 语句的存在对代码没有任何影响。它告诉编译器,如果范围内没有其他 Foo,如何解析简单名称 Foo 的出现。

换句话说,本地作用域仍然具有优先级,即使包括继承的成员。此外,在变量和类型可能出现的地方,变量具有优先权。例如。对于 Foo.bar() 的出现,名为 Foo 的变量具有优先权,局部变量优先于同一类型、外部类或继承类中的成员变量。否则,将使用成员类型、外部类型或继承的成员类型。仅当它们都不存在时,import 语句才会用于解析 Foo

不用说,您应该避免有太多具有相同简单名称的项目,否则您将不得不考虑解析过程的细节。这就是为什么命名约定建议变量名以小写字母开头,类名以大写字母开头。

是的,避免为类指定相同的简单名称。一旦您必须在同一编译单元中处理这两个类,就无法在整个编译单元中使用其(完全)限定名称来访问其中一个类。 (在导入中使用 * 对这种情况没有任何帮助)

<小时/>

正如所解释的,术语“完全”在 Java 中已经过时,因为限定名称始终是完整的。

关于java - Java 中包相对标识符路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51162872/

相关文章:

java - 验证业务规则

java - Java中如何比较字符串和对象

javascript - 从 Chrome 开发工具访问变量(js 命名空间)

python - 在子包之间共享模块的最佳实践是什么?

java - Google App Engine 用户代理

java - 将属性添加到节点时,Neo4j 数据库会因 Lucene 日志而爆炸

java - JAXB:如何注释类以便它们属于不同的 namespace ?

python-3.x - 如何使用 Python 3 中的迭代器重新分配多个变量(如果可能)

python - 使用 doxygen 记录 Python 包

python-3.x - 在 Jupyter Notebook 中安装 feature_selector 时如何解决 egg_info 错误?