提供Java库,但隐藏一些类

14

我正在开发一个基于Java ME的应用程序,希望将其提供为库。有没有办法隐藏我不想让每个人都使用但又是必需的类,以使库正常工作?

更新: 我知道我可以省略public关键字,但在不创建不同的包的情况下如何构建库本身呢?我喜欢将不同的包视为简单的不同文件夹,从而可以很好地组织代码。然而,在某些情况下,我可能需要访问其他包中的类,因此这是相当棘手的。包到底代表什么?一个想法可能是创建“接口”,但这些接口必须声明为public,这意味着外部人员也可以实现预期仅用于库内部某些过程的接口,对吗?


2
将类设置为final只会禁止其子类化,但它仍然会被公开。 - thunderflower
根据你所说的“想要”的含义以及你想要付出多少努力而定。例如,通过反射来绕过访问修饰符相当容易。 - CurtainDog
1
是的,但是当我在Eclipse中包含我的API的jar文件时,如果我展开jar文件的内容,所有类都会显示出来。因此,我想声明它们为final是解决方案的一部分,以确实防止任何人使用它们。但是,如果我有一个API,也许我还想在API内部有不同的包。但是,如果我不使用public修饰符进行声明,那么我就无法按照自己的意愿访问API的不同部分。创建不同包的“正常”原因是什么?我的意思是,我可以将所有代码放在同一个包中,但是库就不会很有结构了... - Thomas Johansson
https://softwareengineering.stackexchange.com/questions/256987/when-creating-a-library-is-there-a-way-to-make-certain-classes-entirely-interna - Suragch
6个回答

5

设置您的库API时,您需要保护任何不想暴露的内容。要做到这一点,只需省略访问修饰符:

class fooBar {
    // do stuff here    
}

这将把类访问设置为“default”,允许在同一包中以及任何子类中从中访问fooBar

在您的类中,您还希望通过标记它们为privateprotected或省略修饰符来锁定任何方法和成员的访问权限,以便根据需要使它们变为“default”。

  • private仅允许从包含类访问;
  • “default”(无修饰符)允许从包含类和包内访问;以及
  • protected允许从同一类、包和任何子类中访问。

对于您公开的任何内容(public),如果不打算重写,将其标记为final也是一个好习惯。

基本上,尽可能地锁定所有内容。更小的API易于使用并且更难被破坏。如果您发现未来需要公开某些内容,请在未来完成。扩展API要容易得多,而不是弃用其部分。


2
谢谢!但正如你所说,我只能在同一包中使用fooBar类。Java项目的通常结构是什么?我一直在创建基于类不同功能的包。例如,我有一个称为com.comms的包,其中存储了通过套接字传输的例程和类。然后我有另一个(应用级别)包,它使用comms包。但我想,为了创建这样的API,我应该将所有类放在同一个包中? - Thomas Johansson
7
好的,当你有一个包含多个程序包的库时,你应该怎么做呢? - Bastien Beurier
默认情况下,类具有默认可见性,因此可见性仅限于包内。您还可以将其明确设置为受保护,并且它也将起到相同的作用。 - Tarun Deep Attri

3
如果可以使用Java 9,使用Jigsaw模块。如果不行,则将每个类放在同一个包中,并为隐藏类提供包级别的访问权限,使用Maven模块进行组织。
我在我的名为coronata的项目中完全按照这样做了,它是一个Wii Remote Java库。几乎所有的类都在com.github.awvalenti.bauhinia.coronata包中,但在不同的模块中(在IDE中显示为项目)。
可见的类是公共的。它们位于以下模块中:
  • coronata-api
  • coronata-builder
  • coronata-demos
  • coronata-lib
隐藏类具有包级别的访问权限。它们位于以下模块中:
  • coronata-common:通用的Coronata库
  • coronata-implementation-bluecove:使用Bluecove实现的Coronata库
  • coronata-implementation-wiiusej:使用Wiiusej实现的Coronata库

2

您可以将类设置为包可见,这样只有在同一包中的其他类才能看到它们。 如果不可行,则可以使用ProGuard混淆类并隐藏其实现。


你不能在类中使用 protected 修饰符,只能用于成员。限制访问类的唯一方法是省略 public 修饰符,使其仅在其包内可见。 - Muzikant

0

让我们考虑一个例子:

如果您有一个类A,想要隐藏它,并且有一个类B,使用类A的功能,则可以这样做:

class B{
//Attribute and Methods

    //Inner class A
    class A{
      //Methods and Attributes.
    }

}

在这样做之后,您可以在类B的方法内创建类A的对象,因此可以使用它。尽管该类将对其他类隐藏,但仍然可以使用它。

将一个类设置为 internal 并不会将其从外部世界隐藏起来。你仍然可以导入并使用它。但是,你所使用的包级访问将会将这些类从其他包中隐藏起来。 - André Willik Valenti

-2

是的,有这种方法。

只需要不将这些类声明为public即可。换句话说,不要使用public关键字,如下所示:

class Internal { // rather than "public class Internal"
    ...
}

默认情况下,类只能在定义它们的包内访问。


-4

你需要将不想公开的类设置为受保护的。这样可以使它们无法从客户端代码中使用。在官方文档中了解更多信息。


你需要的部分是:在类声明中省略 'public' 关键字,这样该类只能被同一包中的其他类访问。 - brabster
1
你不能在类中使用 protected 修饰符,只能用于成员。限制访问类的唯一方法是省略 public 修饰符,使其仅在其包内可见。 - Muzikant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接