在 jar 文件中隐藏类

发布于 2024-10-14 00:07:00 字数 154 浏览 5 评论 0原文

难道真的不可能在jar文件中隐藏一些类吗?

我不想允许直接实例化类以使其更加灵活。这个罐子只能看到工厂(或正面)。

除了创建两个项目之外,还有其他方法可以解决这个问题吗? (两个项目:第一个包含类(实现),另一个引用第一个项目并包含工厂;稍后将仅引用第二个项目)

Is it really impossible to hide some classes in a jar file?

I wanted not to allow direct instantiation of the classes to keep it more flexible. Only the factory (or a facade) should be visible of this jar.

Is there any other way than solve this problem than creating two projects?
(Two projects: the first one contains the classes (implementation) and the other one references to the first one and contains the factory; later only the second one will be referenced)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

时光暖心i 2024-10-21 00:07:00

我认为如果您的公共工厂方法尝试返回“隐藏”的内容,您将会遇到编译器失败或警告。

不,如果不重新实现您自己的 ClassLoader 或使用 OSGi 或类似的东西,您就无法隐藏公共类。

您可以做的是将接口 api 与实现分开,例如,有一个仅包含接口的项目和另一个包含实现的项目。但是,您仍然无法隐藏实现类。

I think you will have either compiler failure or warning if your public factory method try to return something which is "hidden".

No, you can not hide a public class without reimplementing your own ClassLoader or using OSGi or anything similar.

What you can do is to separate interface api from the implementation, e.g. have one project which contains only the interfaces and another porject which contains the implmentations. However, you still cannot hide the implementation classes.

漫漫岁月 2024-10-21 00:07:00

混淆可以以某种方式帮助您。

Obfuscation can help you somehow.

云柯 2024-10-21 00:07:00

对于标准类加载器和普通的旧 jar 文件,这是不可能的。 OSGi 的概念是仅使某些包对另一个包可见(即公共 api 和内部实现的分离)。

如果您使用的是 eclipse,则可以使用 this 强制执行此类规则

With standard classloaders and plain old jar files, this is not possible. OSGi has this concept of making visible only some packages to another bundle(i.e. separation of public api and internal implementation).

If you are using eclipse, you may enforce such rules with this

差↓一点笑了 2024-10-21 00:07:00

如果我正确理解你所说的“不允许直接实例化类以保持更灵活”,那么正确执行的外观模式将处理这个问题。

将要隐藏的所有类的构造函数限制在包范围内。将外观类开放到公共范围。

http://mindprod.com/jgloss/packagescope.html

“如果你有一个变量或方法
你的班级不想要客户
你的班级直接访问,
不要将其公开、受保护或
私人声明。由于一个
Java 设计中的疏忽,你
无法显式声明默认值
“包”可访问性。其他成员
包的上面就能看到它,
但包外的类
继承你的,不会。这
受保护的可访问性属性
提供稍微更明显的效果。一个
受保护的方法可见
继承类,甚至不是类的一部分
同一个包。包范围
(默认)方法不是。那就是
受保护和受保护之间的唯一区别
包范围。 ”

If I understand you correctly when you say "not to allow direct instantiation of the classes to keep it more flexible", a properly executed facade pattern will handle this.

Restrict the constructors of all the classes you want to hide to package scope. Open the facade class to public scope.

http://mindprod.com/jgloss/packagescope.html

"If you have a variable or method in
your class that you don’t want clients
of your class directly accessing,
don’t give it a public, protected or
private declaration. Due to an
oversight in the design of Java, you
can’t explicitly declare the default
“package” accessibility. Other members
of the package will be able to see it,
but classes outside the package that
inherit from yours, won’t. The
protected accessibility attribute
offers slightly more visibibily. A
protected method is visible to
inheriting classes, even not part of
the same package. A package scope
(default) method is not. That is the
only difference between protected and
package scope. "

一场信仰旅途 2024-10-21 00:07:00

我知道您不想隐藏实际的类,只是防止它们在工厂类之外构建。我认为通过在类构造函数中使用包私有(默认)可见性可以很容易地实现这一点。唯一的限制是您需要将类和工厂放在同一个包中,因此在中型到大型代码库中,事情可能会变得不必要的复杂。

I'm understanding you're not looking to hide the actual classes, just prevent their construction outside a factory class. This I think can be quite easily achieved by using package private (default) visibility in the class constructors. The only limitation is that you'll need to have the classes and the factory in the same package so in a medium to large codebase things may get unnecessarily complex.

此生挚爱伱 2024-10-21 00:07:00

如果我正确理解你的问题,你想确保你的库的用户被迫使用你的工厂来实例化他们的对象,而不是使用构造函数本身。

在我看来,有两种可能性,其中一种很愚蠢,但在少数特定情况下可用,另一种是最实用、可能也是最常用的方法。

  1. 你可以把你所有的课程变成
    私有内部类
    工厂。如果你有的话这会起作用
    每个班级一个工厂,但几乎没有
    如果你有很多的话可行
    不同类别的管理
    通过一个工厂。
  2. 您可以使用 protected 访问修饰符
    限制对您班级的访问
    构造函数。 这很常见
    使用工厂时的实践

    模式

If I understand your question correctly, you would like to make sure that users of your library are forced to use your factory to instantiate their objects rather than using the constructors themselves.

As I see it there are two possibilities, one of which is silly but usable in few, specific cases, and the other one is the most practical and probably most commonly used way of doing it.

  1. You could make all your classes into
    private inner classes of the
    factory. This would work if you had
    one factory per class, but is hardly
    workable if you have a lot of
    different classes being managed
    through one factory.
  2. You could use the protected access modifier to
    restrict access to your class
    constructors. This is common
    practice
    when using the factory
    pattern
    .
我的鱼塘能养鲲 2024-10-21 00:07:00

您可以使用自定义类加载器实现这样的魔法,但是:

  • 正确的分离仅在配备有您的类加载器的项目中可用;
  • 创建这样的加载器的努力是否值得真的值得怀疑。

在这种情况下,我会做一些类似于我们在标准 Java 中看到的事情。例如,您看到javax.xml.stream.XMLInputFactory,但在某个地方您有com.sun.xml.internal.stream.XMLInputFactoryImpl。 它是完全可以编译的

new com.sun.xml.internal.stream.XMLInputFactoryImpl()

如果您编写:尽管您几乎不会这样做,但 :-) 使用系统属性,您可以控制正在加载的实际实现。对我来说,这种方法在很多情况下都很好。

我希望我正确理解了你的问题;)

干杯!

You can do such magics with a custom class loader but:

  • the correct separation will be available only in a project staffed with your class loader;
  • it's really doubtful that the effort to create such loader is worthy.

In such situations I would do something similar to what we may see in the standard Java. E.g.you see javax.xml.stream.XMLInputFactory but somewhere you have com.sun.xml.internal.stream.XMLInputFactoryImpl. It is perfectly compilable if you write:

new com.sun.xml.internal.stream.XMLInputFactoryImpl()

though you will hardly do it :-) With a system property you may control the actual implementation that is being loaded. To me such approach is fine in many situations.

I hope I have understood your question correctly ;)

Cheers!

尐籹人 2024-10-21 00:07:00

您的问题有两种解决方案,不涉及将所有类保留在同一个包中。

第一种是使用 Friend Accessor/Friend Package 模式(实用 API 设计,图拉赫 2008)。

第二种是使用OSGi。有一篇文章这里解释OSGi 如何实现这一点。

相关问题: 12,< a href="https://stackoverflow.com/questions/4647599/why-friend-directive-is-missing-in-java">3 和 4

There are two solutions to your question that don't involve keeping all classes in the same package.

The first is to use the Friend Accessor/Friend Package pattern described in (Practical API Design, Tulach 2008).

The second is to use OSGi. There is an article here explaining how OSGi accomplishes this.

Related Questions: 1, 2, 3, and 4.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文