简体   繁体   中英

Should classes with same names in the same packages in different deployment units conflict in Java

I'm seeing an interesting behavior in some of the code I inherited where there's a project with a dependency jar in which there exists a class with the same name and in the same package as a class in the project:

Eclipse project:

src/com.abc.dE

depends on XYZ.jar in which there exists a com.abc.dEclass

Just curious if this setup is legal in Java. According to Eclipse, which doesn't mark it as an error and allows to create a new class that shadows an existing class in a dependency jar, except when one tries to rename such an existing class in the workspace - then it produces the following warning:

"Binary references to a refactored element have been found. They will not be updated, which may lead to problems if you proceed."

And then this forward refactoring is allowed. However, if one would like to refactor backwards to a conflicting name, the following message appears in Eclipse:

"Type named 'E' already exists in package 'com.abc.d'

So is it

  • a correct Java
  • an allowed inconsistency in Eclipse's behavior or
  • .an Eclipse bug?

Thank you.

If both classes where accessible to the same classloader (for example if both jar files find themselves on the same classpath), then only one of them would be loaded (probably the one that's first in the list), which would lead to all kinds of nasty results, esepcially if they don't behave the same.

Assume library 1 uses E.frobnicate() while library 2 expects there to be a E.frob() method: one of those will get a NoSuchMethodError and generally just fail spectacularly.

Generally speaking, the package name and class name should uniquely identify a class. And if that's no longer the case then you'll get into trouble.

You can work around the issue as long as you never need those two libraries to be accessible from the same classloader, then the JVM can handle it just fine (because FQCN plus the classloader is used internally by the JVM to uniquely identify a class during runtime).

The only case where this is intentionally done is if some library re-implements classes of another one in a binary-compatible manner. See log4j-over-slf4j for an example.

There's nothing that states you cannot have two classes with the same package/class name.

This happens all the time when you accidentally have two versions of a library on your classpath, leading to things like IncompatibleClassChangeError or getting the wrong version because you're at the mercy of class load order.

Eclipse, OTOH, has to do something with those classes other than just loading the first one encountered on the classpath. You can't rename to something that already exists, because that wouldn't make any sense.

Renaming something out from under something that already exists is likely an error, but can't be guaranteed to be an error, because you might be fixing a naming problem, rather than just creating a new/different one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM