【问题标题】:Combining assert statement and instanceof pattern matching组合 assert 语句和 instanceof 模式匹配
【发布时间】:2022-11-24 04:46:53
【问题描述】:

在 Java 19 中,我试图在 assert 语句中使用 instanceof 模式匹配。 我希望匹配的类型在语句之后可用,但 Java 编译器不识别新变量。

我们创建了一个变量Object obj,我们无法知道它包含Integer还是String。 我们将变量传递给两个测试方法。

public class AssertPatternMatching {
    public static void main(String[] args) {
        Object obj = args.length == 0 ? Integer.valueOf(42) : "Hello";

        afterAssert(obj);
        insideMessage(obj);
    }

在方法afterAssert()中,我们断言obj是一个String,并通过instanceof模式匹配将字符串绑定到新变量str。 我希望 str 在下一行中被知道和使用。 但是,编译器不知道符号str

    private static void afterAssert(Object obj) {
        assert obj instanceof String str;
        str.length(); // javac: cannot find symbol variable str
    }

在方法insideMessage()中,我们使用复杂的assert语句来检查obj不是String。如果是,则断言失败,我们可以提供一条消息。 由于 instanceof 检查被否定,模式匹配 str 变量应该可用于错误消息。 然而,编译器还是不知道符号str

    private static void insideMessage(Object obj) {
        assert !(obj instanceof String str) : "Is a string: " + str.length();
        // line above: javac: cannot find symbol variable str
        obj.hashCode();
    }

如果我们将 assert 语句替换为 if,它就会起作用:

private static void afterAssertIf(Object obj) {
    if(obj instanceof String str) {
        str.length();
    } else {
        throw new AssertionError();
    }
}

private static void insideMessageIf(Object obj) {
    if (!(obj instanceof String str)) {
        obj.hashCode();
    } else {
        throw new AssertionError("Is a string: "+ str.length());
    }
}

内部消息()example 确实是一个边缘案例,所以我知道它不受支持。 我本来以为后断言()但是,要工作。 这是故意的设计选择还是错误? 如果是故意的,理由是什么?

完整代码在https://gist.github.com/enikao/57bb1b10ce3126494ec4baa2bc7db2df

【问题讨论】:

    标签: java pattern-matching assert instanceof


    【解决方案1】:

    assert声明是只要当使用 -ea 启用断言时执行。没有-ea,代码是不是执行,因此变量永远不会被分配/不存在(这是默认值)。

    private static void afterAssert(Object obj) {
        assert obj instanceof String;
        ((String) str).length();
    }
    

    【讨论】:

    • -ea 是一个运行时标志,对吧?那应该不会影响编译器吧?
    猜你喜欢
    • 2020-09-08
    • 2014-07-18
    • 2020-05-08
    • 2021-04-26
    • 2020-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-06
    相关资源
    最近更新 更多