是否可以使用两个具有相同名称和相同包的java类?

是否可以使用两个具有相同名称和相同包的java类?,java,Java,是否可以在java中导入和使用两个具有相同名称和包的不同类 例如,假设我有两个名为“com.foo.Bar”的类,它们略有不同。我希望两者都能使用,但我有一个限制(因为愚蠢的反射废话),迫使我保持名称和包相同 java是否有一些特性允许我导入和隔离这些类 更详细地说,我改变了我的avro模式,而这些模式本不应该被改变(oops!),现在我想返回并将不能用新模式读取的旧avro文件更改为可以用新模式读取的文件。Avro似乎强迫您使用特定的类和包名来加载文件 不,java包的使用正是为了避免这个问题

是否可以在java中导入和使用两个具有相同名称和包的不同类

例如,假设我有两个名为“com.foo.Bar”的类,它们略有不同。我希望两者都能使用,但我有一个限制(因为愚蠢的反射废话),迫使我保持名称和包相同

java是否有一些特性允许我导入和隔离这些类


更详细地说,我改变了我的avro模式,而这些模式本不应该被改变(oops!),现在我想返回并将不能用新模式读取的旧avro文件更改为可以用新模式读取的文件。Avro似乎强迫您使用特定的类和包名来加载文件

不,java包的使用正是为了避免这个问题。

java中没有名称空间,只有C#中才有,所以我想你指的是包。每个项目只能有一个完全限定的名称。

从技术上讲,可以使用一些低级技巧(如重写字节级代码)来完成。据我所知,不同的java加密机/加密机都是这样工作的——它们有很多类,称为a.class B.class C.class等等。

如果你确实必须这样做,你可以通过使用不同的类加载器和可能的反射来实现


这不是Java的工作方式,也不是故意允许的——你不应该做那些会把事情搞砸的蠢事。

是的。您需要实现自己的类加载器并玩一些游戏,以便能够在运行时访问这两个类

我确信这是可能的,因为我遇到了一个很难调试的问题,有人在他们的产品中有一个奇怪的类加载器,它破坏了库的加载,并从库的两个不同版本提供了同一文件的两个不同版本

然而,这听起来是一个非常糟糕的主意。我会回去找一个不同的方法来解决你的问题。从长远来看,这只会让你心痛。见鬼,当您调查类装入器时,它可能已经存在了


编辑:具体来说,您不能同时“导入”这两种内容。但是您可以在运行时访问这两个属性。

我觉得您需要在一个名为com.foo.Bar的接口中定义方法签名。然后提供两种不同的接口具体实现(比如com.foo.DefaultBar和com.foo.SpecialBar)。这样,您可以针对接口类型进行编程,并根据需要在两种不同的实现之间切换

你能详细解释一下你所说的“反射垃圾”是什么意思吗?这可能会让你深入了解你的确切问题


不要弄乱类加载器或任何其他低级欺骗。解决此类问题的最佳方法是,首先要有一个清晰的设计,任何人都能理解。

正如前面提到的那样,编写自己的类加载器,或者另外使用像Equinox这样的OSGi框架来为您加载类。

是的。不过,它确实需要您自己制作类加载器


我在github上做了一个很好的例子

我认为包装类的想法行不通。设两个同名类为C1和C2;以及它们各自的包装物W1和W2。类加载器将(1)加载W1,这将导致它(2)加载C1。然后类装入器将(3)装入W2。它会认为它已经加载了C2(因为名称相同),而您的W2类将包装C1。我们以应该的方式更改了avro模式,因此我正在尝试编写一个hadoop作业来修复使用旧模式的文件。Avro似乎强迫您使用相同的类和包名。我认为您只需要像希望引用同名类一样多的独立类装入器实例(其中一个可以是引导类装入器)。实际上,您不需要为此编写自己的类加载器,它不必是低级的或诡计的。单独的类装入器实例是一种方法。如果顶级类型的名称显示为同一包中声明的任何其他顶级类或接口类型的名称,则这是一个编译时错误。