今天,我将Java版本从16更新到17,我发现sealed类是其中的一个新功能。我认为可以这样声明:
public sealed class Main permits AClass, AnotherClass {
}
Run Code Online (Sandbox Code Playgroud)
但是,Java 中的密封类有什么用呢?
我还知道这是JDK 15中的预览功能。
随着 Kotlin1.5的推出sealed interface,. 即使我知道类和接口之间的区别,我也不清楚使用sealed interfaceover的最佳实践和好处是什么sealed class
interface即使是简单的情况,我是否应该始终使用now ?还是将视具体情况而定?
谢谢
Obs:没有发现类似的问题,只是关于sealed classes
我真的不明白为什么non-sealedJEP 360/Java 15 中有一个关键字。对我来说,密封类的扩展应该只是 final 或密封类本身。
提供“非密封”关键字将邀请开发人员进行黑客攻击。为什么我们允许将密封类扩展为非密封类?
我想基于一个创建一个颜色对象Int.我可以使用sealed class和获得相同的结果,enum并且想知道一个是否比另一个好.
使用sealed class:
sealed class SealedColor(val value: Int) {
class Red : SealedColor(0)
class Green : SealedColor(1)
class Blue : SealedColor(2)
companion object {
val map = hashMapOf(
0 to Red(),
1 to Green(),
2 to Blue()
)
}
}
val sealedColor: SealedColor = SealedColor.map[0]!!
when (sealedColor) {
is SealedColor.Red -> print("Red value ${sealedColor.value}")
is SealedColor.Green -> print("Green value ${sealedColor.value}")
is SealedColor.Blue -> print("Blue value ${sealedColor.value}")
}
Run Code Online (Sandbox Code Playgroud)
使用enum:
enum …Run Code Online (Sandbox Code Playgroud) 不确定是否可能,但对于我的一生,我不知道如何序列化它。
sealed class ServiceResult<out T : Any> {
data class Success<out T : Any>(val data: T) : ServiceResult<T>()
data class Error(val exception: Exception) : ServiceResult<Nothing>()
}
Run Code Online (Sandbox Code Playgroud)
T 中的所有内容都使用 @Serialized ex:
@Serializable
data class GalleryDTO(
override val id: Int,
override val dateCreated: Long,
override val dateUpdated: Long,
val name:String,
val description:String,
val photos:List<DTOMin>
) : DTO
Run Code Online (Sandbox Code Playgroud) 到目前为止,我一直在使用此Kotlin密封类:
sealed class ScanAction {
class Continue: ScanAction()
class Stop: ScanAction()
... /* There's more but that's not super important */
}
Run Code Online (Sandbox Code Playgroud)
这在我的Kotlin和Java代码中都非常有效。今天,我尝试更改此类以改为使用对象(建议这样做,以减少额外的类实例化):
sealed class ScanAction {
object Continue: ScanAction()
object Stop: ScanAction()
}
Run Code Online (Sandbox Code Playgroud)
我可以在其他Kotlin文件中引用这种简单的方法,但是现在我正努力在Java文件中使用它。
我尝试了以下操作,并且在尝试使用Java进行引用时,这两种方法都会反汇编错误:
ScanAction test = ScanAction.Continue;
ScanAction test = new ScanAction.Continue();
Run Code Online (Sandbox Code Playgroud)
有谁知道我现在该如何引用Java中的实例?
密封类和密封接口是Java 15中的一个预览功能,在 Java 16 中有第二个预览,现在建议在 Java 17 中交付。
他们提供了典型的例子一样Shape- > Circle,Rectangle等等。
我理解密封类:switch提供的语句示例对我来说很有意义。但是,密封接口对我来说是个谜。任何实现接口的类都被迫为它们提供定义。接口不会损害实现的完整性,因为接口本身是无状态的。我是否想将实现限制为几个选定的类并不重要。
你能告诉我 Java 15+ 中密封接口的正确用例吗?
Kotlin 1.7when中将禁止对密封类/接口进行非详尽的声明。
我有一个sealed class State和它的孩子:
sealed class State {
object Initializing : State()
object Connecting : State()
object Disconnecting : State()
object FailedToConnect : State()
object Disconnected : State()
object Ready : State()
}
Run Code Online (Sandbox Code Playgroud)
在某些情况下,我只想处理特定的项目,而不是全部,例如:
val state: State = ... // initialize
when (state) {
State.Ready -> { ... }
State.Disconnected -> { ... }
}
Run Code Online (Sandbox Code Playgroud)
但我收到一条警告(在Kotlin 1.7中我猜这将是一个错误),说:
1.7 中将禁止在密封类/接口上使用非详尽的“when”语句,而是添加“Connecting”、“Disconnecting”、“FailedToConnect”、“Initializing”分支或“else”分支
else -> {}像下面的代码一样在这里使用空分支是一个好习惯吗?
when (state) {
State.Ready -> { ... }
State.Disconnected -> …Run Code Online (Sandbox Code Playgroud) 如果我声明以下密封层次结构
package a;
import b.B;
public sealed interface A permits B {
}
Run Code Online (Sandbox Code Playgroud)
package b;
import a.A;
public record B() implements A {
}
Run Code Online (Sandbox Code Playgroud)
不使用模块(没有 module-info.java)并尝试用 Maven 编译它我得到
[ERROR] .../src/main/java/a/A.java:[5,35] class a.A in unnamed module cannot extend a sealed class in a different package
Run Code Online (Sandbox Code Playgroud)
我知道https://openjdk.java.net/jeps/409和本节:
由 permit 指定的类必须位于超类附近:在同一个模块中(如果超类在命名模块中)或在同一个包中(如果超类在未命名模块中)。
但是,Maven 在编译时不应该默认使用类路径吗?能否完全避免这种限制?
如果不是,这不是开创了一个先例,其中模块路径上的功能比类路径上的功能更灵活,反过来 - 虽然仍然支持类路径,但与模块路径相比,它不像以前那样是一等公民?