Java 类名与嵌套包名相同

2022-01-13 00:00:00 package java

在我的 Java 应用程序中,我使用了第三方库.

In my Java application, I use a third-party library.

但是我发现了一些奇怪的东西,有一些嵌套的包,还有一些类的名字可能和包的名字一样.

However, I found something strange, there are some nested packages, and some classes whose name may be the same as the name of the package.

恐怕我说不清楚.这是一个例子:

I am afraid I can not make it clear. Here is an example:

包装

  com.xx.a
  com.xx.a.a

在 'com.xx.a' 中有一个名为 'a' 的类.

And there is a class named 'a' inside the 'com.xx.a'.

所以如果我想把这个类称为'a'......

So if I want to call this class 'a'...

我写:

a ma = new com.xx.a.a();

那么 IDE 会认为我的意思是包 'com.xx.a.a'.

Then the IDE will think that I mean the package 'com.xx.a.a'.

那我就不能叫了.

不知道为什么?

顺便说一句,库提供者似乎不希望我们使用这些类.

By the way, it seems that the library provider did not want us to use these kinds of classes.

他们是怎么做到的?

推荐答案

Java 语言允许类标识符被包标识符隐藏.在您的情况下,class com.xx.a 被 package com.xx.a 所掩盖.

The Java language allows class identifiers to be obscured by package identifiers. In your case the class com.xx.a is obscured by the package com.xx.a.

来自 Java语言规范:

6.3.2 模糊声明

简单名称可能出现在可能被解释为变量、类型或包的名称的上下文中.在这些情况下,§6.5 的规则指定将优先选择变量而不是类型,并且将优先选择类型而不是包.因此,有时可能不可能通过其简单名称来引用可见类型或包声明.我们说这样的声明被掩盖了.

A simple name may occur in contexts where it may potentially be interpreted as the name of a variable, a type or a package. In these situations, the rules of §6.5 specify that a variable will be chosen in preference to a type, and that a type will be chosen in preference to a package. Thus, it may sometimes be impossible to refer to a visible type or package declaration via its simple name. We say that such a declaration is obscured.

我必须说,第 6.5 节中对标识符含义进行分类的规则还很不明确.

I must say that the rules in §6.5 for classifying the meaning of an identifier are far from clear though.

您仍然碰巧拥有违反此规则的库副本的原因是该规则不适用于类文件/JAR 文件和JVM.

The reason why you still happen to have a copy of a library that violates this rule is because the rule does not apply for class files / JAR files and the JVM.

这意味着您可以在 JAR 文件中存在此类命名冲突,但您永远不会将其视为 javac 的输出.产生这些类/包名称的工具很可能是一个代码混淆器,它产生这种混乱的代码来压缩文件的大小并混淆代码以防止逆向工程.

This means that you can have such naming conflicts in JAR files, but you'll never see it as output from javac. The tool that has produced these class / package names is most likely a code obfuscator which produces this kind of messy code to compress the size of the files and to obfuscate the code to prevent reverse engineering.

PS.仔细一看,它实际上可能是 Eclipse 方面的一个错误(假设那是您正在谈论的 IDE).通过让空包名与类名冲突,Eclipse 会阻塞 javac 接受的内容.规范很难遵循,但据我所知,javac 在这种情况下遵循规范.

PS. At a closer look it may actually be a bug on the Eclipse side (assuming that's the IDE you're talking about). By letting an empty package name collide with a class name, Eclipse chokes on something javac accepts. The spec is hard to follow, but from what I can see, javac follows the spec in this case.

相关文章