Kotlin 中的包保护替代方案
Package protected alternative in Kotlin
在 Java 中,我们有 类 的包保护(默认)修饰符,它允许我们在一个包中有许多 类 但只公开一些并保持封装的逻辑。
对于 Kotlin,情况似乎并非如此。如果我想让几个 类 彼此可见但不再可见,我必须使用 private 修饰符来限制对单个文件的可见性。
所以如果你想在一个包中包含 10 个 类 但其中只有一个 public,你必须有一个包含所有 类 的大文件(而且到处都是 private
)。
这是正常做法还是有一种方法可以在 Kotlin 中实现某种类似的模块化?
我不明白:如果他们有包的概念,为什么要取消包保护访问?
更新:毕竟我们可能有包保护可见性
see the discussion here
更新:如果您通读讨论后仍然认为这是该语言的必备功能,请投票here
与 Java 相比,Kotlin 似乎对包模型的依赖程度较低(例如,目录结构未绑定到包)。相反,Kotlin 提供 internal
visibility, which is designed for modular project architecture. Using it, you can encapsulate a part of your code inside a separate module.
因此,您可以在顶级声明中使用
private
限制对文件的可见性
internal
限制模块可见性
此时,没有其他可见性限制选项。
正如@hotkeys 指出的那样,您可以在 module 中使用 internal
关键字,或者您可以将原本属于一个包的所有 类 放在一个文件中,但在文件中粘贴多个 类 可能是一个有问题的设计决定。
对我来说,package
可见性有助于其记录价值。我想知道某些包呈现给项目其余部分的 public 接口是什么,隐藏工厂实现 类 等等。
所以即使可以访问包私有类和Java中的方法,我仍然选择使用package
修饰符。
为此,我创建了一个带有单个注释的项目:
package com.mycompany.libraries.kotlinannotations;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Documented
@Retention(SOURCE)
@Target({ TYPE, METHOD, CONSTRUCTOR })
/**
* Use in Kotlin code for documentation purposes.
*
* Whenever a Kotlin class or method is intended to be accesible at package level only.
*
*/
public @interface PackagePrivate {
}
然后我可以在任何 Kotlin 项目中使用这个注释。
我还没有完成的第二步是创建一个 PMD 规则以使用 maven(或任何其他构建工具)强制执行此操作,并且还能够在我的 IDE 使用 pmd 插件。
pmd at this moment 中没有完整的 Kotlin 支持,但似乎在某些时候是可以预期的。
作为我在 android 上的解决方法,我创建了 @PackagePrivate
注释和 lint 检查来控制访问。 Here你可以找到项目。
Lint 检查显然不像编译器检查那么严格,并且需要一些设置才能使构建失败。但是 android studio 会自动进行 lint 检查并在输入时立即显示错误。不幸的是,我不知道如何从自动完成中排除带注释的成员。
此外,由于 lint 是一个纯粹的编译时工具,因此不会在运行时执行任何检查。
基于包的保护在 Kotlin 中毫无意义,因为包本身不受保护
在 Java 中,包与目录结构相关联。因此,如果您将 classes 放在 com\example\yoursecretengine
中,任何试图(有意或无意)添加流氓 class 的行为都会很容易被注意到。这就是我们所依赖的安全保障。
Kotlin 删除了目录和包之间的联系,所以我可以将我的 class 放在“我的”目录中(例如 src\java\pl\agent_l\illegalaccess
),但将其包声明为 com.example.yoursecretengine
- 并且获得对您作为包私有的所有属性的访问权限。
事实上,Kotlin 项目无需任何包声明即可完美运行。这只是强调了软件包“比实际规则更像你所说的指南”。它们是一项便利功能,仅对整理命名空间有用,仅此而已。
unlike many other languages, Kotlin packages do not require files to have any specific locations w.r.t. itself; the connection between a file and its package is established only via a package header.
并且:
an absence of a package header in a file means it belongs to the special root package.
在 Java 中,我们有 类 的包保护(默认)修饰符,它允许我们在一个包中有许多 类 但只公开一些并保持封装的逻辑。
对于 Kotlin,情况似乎并非如此。如果我想让几个 类 彼此可见但不再可见,我必须使用 private 修饰符来限制对单个文件的可见性。
所以如果你想在一个包中包含 10 个 类 但其中只有一个 public,你必须有一个包含所有 类 的大文件(而且到处都是 private
)。
这是正常做法还是有一种方法可以在 Kotlin 中实现某种类似的模块化?
我不明白:如果他们有包的概念,为什么要取消包保护访问?
更新:毕竟我们可能有包保护可见性
see the discussion here
更新:如果您通读讨论后仍然认为这是该语言的必备功能,请投票here
与 Java 相比,Kotlin 似乎对包模型的依赖程度较低(例如,目录结构未绑定到包)。相反,Kotlin 提供 internal
visibility, which is designed for modular project architecture. Using it, you can encapsulate a part of your code inside a separate module.
因此,您可以在顶级声明中使用
private
限制对文件的可见性internal
限制模块可见性
此时,没有其他可见性限制选项。
正如@hotkeys 指出的那样,您可以在 module 中使用 internal
关键字,或者您可以将原本属于一个包的所有 类 放在一个文件中,但在文件中粘贴多个 类 可能是一个有问题的设计决定。
对我来说,package
可见性有助于其记录价值。我想知道某些包呈现给项目其余部分的 public 接口是什么,隐藏工厂实现 类 等等。
所以即使可以访问包私有类和Java中的方法,我仍然选择使用package
修饰符。
为此,我创建了一个带有单个注释的项目:
package com.mycompany.libraries.kotlinannotations;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Documented
@Retention(SOURCE)
@Target({ TYPE, METHOD, CONSTRUCTOR })
/**
* Use in Kotlin code for documentation purposes.
*
* Whenever a Kotlin class or method is intended to be accesible at package level only.
*
*/
public @interface PackagePrivate {
}
然后我可以在任何 Kotlin 项目中使用这个注释。
我还没有完成的第二步是创建一个 PMD 规则以使用 maven(或任何其他构建工具)强制执行此操作,并且还能够在我的 IDE 使用 pmd 插件。
pmd at this moment 中没有完整的 Kotlin 支持,但似乎在某些时候是可以预期的。
作为我在 android 上的解决方法,我创建了 @PackagePrivate
注释和 lint 检查来控制访问。 Here你可以找到项目。
Lint 检查显然不像编译器检查那么严格,并且需要一些设置才能使构建失败。但是 android studio 会自动进行 lint 检查并在输入时立即显示错误。不幸的是,我不知道如何从自动完成中排除带注释的成员。
此外,由于 lint 是一个纯粹的编译时工具,因此不会在运行时执行任何检查。
基于包的保护在 Kotlin 中毫无意义,因为包本身不受保护
在 Java 中,包与目录结构相关联。因此,如果您将 classes 放在 com\example\yoursecretengine
中,任何试图(有意或无意)添加流氓 class 的行为都会很容易被注意到。这就是我们所依赖的安全保障。
Kotlin 删除了目录和包之间的联系,所以我可以将我的 class 放在“我的”目录中(例如 src\java\pl\agent_l\illegalaccess
),但将其包声明为 com.example.yoursecretengine
- 并且获得对您作为包私有的所有属性的访问权限。
事实上,Kotlin 项目无需任何包声明即可完美运行。这只是强调了软件包“比实际规则更像你所说的指南”。它们是一项便利功能,仅对整理命名空间有用,仅此而已。
unlike many other languages, Kotlin packages do not require files to have any specific locations w.r.t. itself; the connection between a file and its package is established only via a package header.
并且:
an absence of a package header in a file means it belongs to the special root package.