提供 Java 库,但隐藏了一些类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6642909/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 16:45:54  来源:igfitidea点击:

Providing Java library, but hiding some classes

javajava-me

提问by Thomas Johansson

I am developing an application in Java ME that I want to provide as a library. Is there no way to hide classes that I don't want everyone to use, but is essential still in order for the library to work?

我正在 Java ME 中开发一个应用程序,我想将其作为库提供。有没有办法隐藏我不希望每个人都使用的类,但为了图书馆的工作仍然必不可少?

UPDATE: I get that I can omit the public specifier, but how can I structure the library itself while developing without creating different packages? I like to view different packages as different folders simply which allows me to structure the code in a good way. However, in some cases I might need to access classes in other packages so this is rather tricky. What does packages really represents? One idea might be to create "interfaces", but these has to be declared public so that means that foreigners might also implement the interfaces intended only for some processes inside the library, correct?

更新:我知道我可以省略公共说明符,但是如何在开发时构建库本身而不创建不同的包?我喜欢将不同的包视为不同的文件夹,这让我可以很好地构建代码。但是,在某些情况下,我可能需要访问其他包中的类,因此这相当棘手。包裹真正代表什么?一种想法可能是创建“接口”,但这些必须被声明为公开的,这意味着外国人也可能实现仅用于库内某些进程的接口,对吗?

回答by Kim Burgess

For setting up your library API you'll want to protect anything you don't want exposed. Do do this just omit the access modifier:

为了设置你的库 API,你需要保护你不想暴露的任何东西。这样做只是省略访问修饰符:

class fooBar {
    // do stuff here    
}

This will set the class access as 'default' which allows access from within the same package as well as from any classes which subclass fooBar.

这会将类访问设置为“默认”,允许从同一包内以及从 fooBar.

Within your classes you will also want to lock down any access on your methods and members by marking them either private, protectedor omitting the modifier so that they are 'default' as required.

你的类中,你也将要锁定你的方法和成员通过标记他们要么任何访问privateprotected或省略的修改,以便根据需要它们是“默认”。

  • privatewill allow access from the containing class only;
  • 'default' (no modifier) allows from within the containing class and containing package; and
  • protectedwill allow access from within the same class, package and any subclasses.
  • private将只允许从包含类访问;
  • 'default'(无修饰符)允许来自包含类和包含包;和
  • protected将允许从同一类、包和任何子类中访问。

For anything that you have exposed (public) it is also good practice to mark it as finalif it's not designed to be overridden.

对于您已公开的任何内容 ( public),将其标记为final并非旨在覆盖它也是一种很好的做法。

Basically, lock down everything as much as you can. Smaller API's are easier to use and harder to break. If you find something needs to be exposed in the future, do it in the future. It's much easier to expand an API rather than deprecate parts of it.

基本上,尽可能多地锁定一切。较小的 API 更易于使用且更难破解。如果你发现有什么东西需要在未来暴露出来,那就在未来去做。扩展 API 而不是弃用它的一部分要容易得多。

回答by Kim Burgess

You can make the classes package protectedwhich only other classes in the same package can see. If this isn't feasible, then you can use ProGuardto mangle the classes and hide their implementations.

您可以创建package protected只有同一包中的其他类才能看到的类。如果这不可行,那么您可以使用ProGuard来破坏类并隐藏它们的实现。

回答by André Valenti

If Java 9 is possible, use Jigsaw modules. If not, put every class on the same package, with package-level access for hidden classes, and use Maven modulesto organize them.

如果可以使用 Java 9,请使用Jigsaw modules。如果没有,将每个类放在同一个包中,对隐藏类具有包级访问权限,并使用Maven 模块来组织它们。

I've done exactly that in my project called coronata, a Wii Remote java library. Almost all classes are in package com.github.awvalenti.bauhinia.coronata, but on different modules (which appear as projects on the IDE).

我在名为coronata 的项目中完全做到了这一点,这是一个 Wii 远程 Java 库。几乎所有的类都在 package 中com.github.awvalenti.bauhinia.coronata,但位于不同的模块中(在 IDE 中显示为项目)。

Visible classes are public. They are in modules:

可见类是公开的。它们在模块中:

  • coronata-api
  • coronata-builder
  • coronata-demos
  • coronata-lib
  • coronata-api
  • coronata-builder
  • coronata-demos
  • coronata-lib

Hidden classes have package-level acesss. They are in modules:

隐藏类具有包级访问权限。它们在模块中:

  • coronata-common
  • coronata-implementation-bluecove
  • coronata-implementation-wiiusej
  • coronata-common
  • coronata-implementation-bluecove
  • coronata-implementation-wiiusej

回答by Logan

Lets consider an Example:

让我们考虑一个例子:

If you have a class A, that you want to hide, and a class B, that uses the functionality of class A, then you can do this:

如果您有一个要隐藏的 A 类和一个使用 A 类功能的 B 类,那么您可以这样做:

class B{
//Attribute and Methods

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

}

After doing this, you can create an Object of class A inside a method of class B and hence use it. Though the class will be hidden from other classes, it could still be used.

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

回答by NPE

Yes, there is.

就在这里。

Simply don't declare those classes public. In other words, omit the publickeyword like so:

只是不要声明这些类public。换句话说,public像这样省略关键字:

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

By default, classes are only accessible within the package where they are defined.

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

回答by thunderflower

You need to make the classes that you don't want exposed protected. This will make them non usable from client code. Read more in the official docs

您需要使您不想公开的类受到保护。这将使它们无法从客户端代码中使用。在官方文档中阅读更多内容