gpt4 book ai didi

java - 在密封类上的when表达式中使用 `is`是否会在运行时导致反射?

转载 作者:行者123 更新时间:2023-12-02 13:07:44 26 4
gpt4 key购买 nike

在Java中,如果我有这样的类层次结构:

private interface Foo { }

private class FooBar implements Foo { }

private class FooZoo implements Foo { }

然后我有一个像这样的函数:
public int Return0IfFooBarElseIfFooZooReturn1ElseReturn2(Foo foo) {
if (foo instanceof FooBar) {
return 0;
} else if (foo instanceof FooZoo) {
return 1;
} else {
return 2;
}
}

在运行时,将使用反射来确定 foo的类型。在理想的世界中,我们希望避免代码使用反射。另外,据我所知,没有办法在Java中创建密封的类型层次结构,这意味着您将始终需要提供else分支来编译代码。

但是,在Kotlin中,您可以创建密封的类型层次结构,如下所示:
sealed class Foo {
object FooBar : Foo()
object FooZoo : Foo()
}

然后,您可以编写一个when表达式以打开类型并返回一个值,如下所示:
fun return0IfFooBarElseReturn1(foo: Foo) = when (foo) {
is Foo.FooBar -> 0
is Foo.FooZoo -> 1
}

有一个有趣的特性。即,不需要 else,因为 when表达式正在详尽地检查密封类型层次结构。那么,从这个属性,编译器是否可以派生足够的信息来编译字节码,而字节码在运行时将不使用反射来确定所传递的实例是否为给定类型?

换句话说,上面的Kotlin代码与下面的Kotlin代码在运行时是否有任何区别(关于反射):
interface Foo

class FooBar : Foo { }

class FooZoo : Foo { }

fun return0IfFooBarElseReturn1(foo: Foo) = when (foo) {
is FooBar -> 0
else -> 1
}

我之所以这么问,是因为通常作为程序员,我们希望避免反射(在可能的情况下),但是密封类的官方Kotlin文档显示了使用 is( https://kotlinlang.org/docs/reference/sealed-classes.html)打开实例的示例。我还在工作中的代码中也做了类似的工作,尽管我确实没有发现任何问题,但是一些同事却表达了担忧,因为它看起来像是代码的味道。

最佳答案

编译器在后台执行的任何操作都与这是否是好习惯无关。当您使用反射来微管理对象的行为时,反射就是代码的味道,否则它们可能会通过多态性来照顾自己的行为。

就密封类而言,您使用的是一组有限的类,因此对它们的行为进行微观管理并不那么费力,但我认为,如果在定义它们的文件之外进行操作,仍然有些难闻。

这是一个interesting article关于何时应该依赖反射而不是多态。 TLDR:

Polymorphism only makes sense when the polymorphic behavior is really a behavior of the target. When it's the behavior of the observer, you need runtime typing.



因此,如果您的 when语句要求每个对象做某事或计算某事,则可能是应优先考虑多态的情况。如果您的 when语句正在对对象做某事或需要以某种特定方式对其进行排序,则反射可能更合适。

我认为在一个 Realm 中使用密封类是有意义的,当它们是解析文件或Web上的某些内容的返回值时。与 Expr示例中所有内容都可以评估为Double的示例不同,当您从某些不可预测的文件中读取时,返回值可能具有不可预测的类型。您可能需要将返回值排序到特定的处理程序中。否则,返回值可能是一个错误,您处理的错误与有效值不同。

您还可以使用密封类作为检查异常的更好替代方案。通过将结果包装在可以是有效结果持有人或错误的类中,可以强制调用方在需要时处理错误,或者可以使调用方冒泡,而函数签名不必知道有关错误类型的任何信息可能会遇到。然后,无论需要处理什么级别的错误,都可以使用 when语句将其解压缩。

关于java - 在密封类上的when表达式中使用 `is`是否会在运行时导致反射?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60402163/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com