Java class name matches nested package name

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

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

I'm afraid I canโ€™t understand. Here is an example:

package

com.xx.a com.xx.aa 

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

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

Writing:

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

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

Then I canโ€™t name him.

I wonder why?

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

How do they do it?

+2
source share
5 answers

The Java language allows you to hide class identifiers using package identifiers. In your case, the class com.xx.a obscured by the package com.xx.a

From the Java language specification :

6.3.2 Shaded announcements

A simple name can occur in contexts where it can potentially be interpreted as the name of a variable, type, or package . In these situations, the rules of section 6.5 indicate that the variable will be selected in the preference for the type and that the type will be selected in the package preference. Thus, it can sometimes be impossible to refer to the visible type or declaration of a package through its simple name. We say that such an announcement is obscured.

I must say that the rules in section 6.5 for classifying the value of an identifier are far from clear.

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

This means that you can have such name conflicts in JAR files, but you will never see it as output from javac . The tool that created these class / package names is most likely an obfuscator to code that creates such dirty code to compress file sizes and obfuscate code to prevent reverse engineering.


PS. On closer inspection, this may be a mistake on the Eclipse side (assuming you are talking about the IDE). By allowing empty package names to come across a class name, Eclipse is choking on something that javac accepts. Speculation is hard to accomplish, but from what I see, javac follows the specification in this case.

+5
source

You need to do this:

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

Or import the package:

 import com.xx.a; a ma = new a(); 
0
source

The library was probably confused (using proguard, for example) to reduce size, prevent reverse engineering, and โ€œhideโ€ things you shouldn't use. Even if you manage to create an instance of this class, I would recommend against it, since you do not know what it will do, and how it can / should be used.

0
source

we cannot do this in java:

 com.xx.A com.xx.A.yy 

the package name collides with the class in the parent package.

0
source

Sometimes you want to access a package, not a class. But the order for the compiler is a package with a variable type. I had to rename all packages, classes and variables.

For example: int a will become int a_var class a will become class a_class package a package will become a_package

I used eclipse refactoring functions for this.

You still have to go through the classes and rename all conflicts by adding _var, _class or _package. Hard work, but since Eclipse does not know for what reason (String aabc, import abcd), it will still try to find the first variable / type, even if it is a package.

0
source

All Articles