热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

无法访问的代码工作正常-如何?

如何解决《无法访问的代码工作正常-如何?》经验,为你挑选了3个好方法。

从我的理解下面我写了不应该编译的语句代码"我不可达"是后return.

但是,编译绝对正常.

同样来自JLS:无法访问的语句,它不应该编译.

来自规范14.21无法到达的声明:

如果满足以下两个条件,则try语句可以正常完成:

try块可以正常完成,或者任何catch块都可以正常完成.

如果try语句有finally块,则finally块可以正常完成.

这里的try块无法正常完成,但catch块可以和finally块一样,所以我在这里很困惑

    public class Test1 {
     public static void main(String[] args) {
        try {
            return;

        } catch (Exception e) {
            System.out.println("catch");

        } finally {
            System.out.println("finally");
        }
        System.out.println("I am unreachable??!!!");
    }
}

有人能帮我理解这种行为吗?



1> Eran..:

我相信这些是JLS 14.21的相关引用:

如果可以访问,则不是交换机块的空块可以正常完成.

非空交换块的非空块可以正常完成,如果其中的最后一个语句可以正常完成.

如果块可以访问,则非空块中不是交换块的第一个语句是可到达的.

如果S之前的语句可以正常完成,则非空交换块中的每个其他语句S都是可到达的.

所以你的

System.out.println("I am unreachable??!!!");

语句是可达的iff(这意味着"当且仅当")try语句可以正常完成,这导致下一个引用:

如果满足以下两个条件,则 try语句可以正常完成:

try块可以正常完成,或者任何catch块都可以正常完成.

如果try语句有finally块,则finally块可以正常完成.

由于您的catch块可以正常完成并且您有一个finally可以正常完成的块,因此该try语句可以正常完成.因此System.out.println("I am unreachable??!!!");,无论块return;内的语句如何,其后面的语句都被认为是可达的try.

请注意,or

try块可以正常完成,或者任何catch块都可以正常完成.

这要求try至少一个catch块正常完成.它不需要try块和catch块来正常完成.

最后,这种行为背后的逻辑:

编译器不应该分析try块是否可以抛出Exception.原因是Exception类层次结构包括已检查和未经检查的异常,并且未在throws子句中声明未经检查的异常(如果您替换Exception为某些已检查的异常,例如IOException,编译器会抱怨您的try块从不抛出该异常,这会使该catch块不可达).

因此,由于您有一个catch (Exception e)可以正常完成的块,编译器会假定此catch块可以访问,因此整个try语句可以正常完成,即使该try块无法正常完成.

finally块(如果存在)也必须能够正常完成,因为finally块也被执行,因此如果它无法正常完成,则整个try语句无法正常完成.


我觉得chrylis到了那里,但他被打断了.
@chrylis你会在"InterruptedException"中添加什么?
我要添加一件事--`InterruptedException`.
回到实现`Thread.stop(Throwable)`时(除了在调用者处抛出异常),即使是`return`语句也可能因异常而失败.
@chrylis在Java中,术语*中断*用于通过`Thread.interrupt()`来发送信号,它只用"InterruptedException"结束阻塞操作(如`wait()`)或在显式查询时被检测到,即通过`Thread.interrupted()`.相反,通过`Thread.stop(...)`停止可能会强制导致任意代码位置的异常(包括那些试图处理这种异常的异常),这就是为什么它现在被弃用了很长时间甚至不支持最近的JVM用于其他throwables比`ThreadDeath`,它不是`Exception`的子类.
@chrylis不是,所有这一切都设置了*旗*,仅此而已.该旗帜如何被"消费"是一个不同的故事

2> Aman Chhabra..:

你有回报的尝试.

如果有异常并直接捕获该怎么办?因此,它在编译器方面并不可达,并且正在成功编译.

如果您也将获得回收,则编译将失败

另外,根据JLS 14.21:

如果在break目标中没有try块语句包含break语句,或者try语句的try块包含break语句,并且那些try语句的所有finally子句都可以完成,则可达到的break语句将退出语句一般.

当你在try和catch中返回时,请参阅下面的输出:

jshell>  public class Test1 {
   ...>     public static void main(String[] args) {
   ...>         try {
   ...>             return;
   ...>
   ...>         } catch (Exception e) {
   ...>             return;
   ...>
   ...>         }
   ...>
   ...>         System.out.println("I am unreachable??!!!");
   ...>     }
   ...> }
|  Error:
|  unreachable statement
|          System.out.println("I am unreachable??!!!");
|          ^------------------------------------------^

如果在finally语句中返回并且编​​译失败,则会出现类似情况.

如果出现以下情况,将认为声明帖子尝试可达:

1) Try has a return statement with catch and finally not having return statement
2) Try does not have a return statement with catch having or not having return statement and finally not having return statement
3) Try, catch and finally not having return statement



3> Yashi Srivas..:

试图给出问题的更简化原因,代码是可达的,以防try块中发生异常.在这种情况下,控制进一步进入catch块,然后进入finally块.在finally块之后,将执行特定语句.

try {
            return;                                 //line 1

        } catch (Exception e) {
            System.out.println("catch");            //line 2

        } finally {
            System.out.println("finally");          //line 3
        }
        System.out.println("I am unreachable??!!"); //line 4

这意味着,有2个案例,因此有2个流程:

    第1行 - >第3行 - >返回(如果没有异常)

    第1行(发生异常) - >第2行 - >第3行 - >第4行(如果尝试获取异常)

只有当我们不保留任何控制权的可能性时,该线路才会无法到达.有两种方法:

    从catch块返回

    从finally块返回.

在这两种情况下,控件永远不会流向该行.

try {
            return;                                 //line 1

        } catch (Exception e) {
            System.out.println("catch");            //line 2
            return;                                 //return control
        } finally {
            System.out.println("finally");          //line 3
            return;                                 //or return from here
        }
        System.out.println("I am unreachable??!!"); //line 4    

我希望现在能够清楚地了解问题的实际原因.


@YashiSrivastava因为`finally`块中的`return`会覆盖catch块中的任何返回,并且它也会吞下异常.请参阅[此问题](/sf/ask/17360801/)及其答案.
此外,它可以替换**'try`-block(或`catch`-block)中的`return`语句成功评估后返回的值** - 这可能会导致一些头痛:[见这个问题](/sf/ask/17360801/)
@jwenting:也许是SESE纯粹主义者和货物崇拜者.但不是"一般".如果您知道要返回什么,那么返回是最合适的事情.(有很好的理由不在"finally"块中返回,但它们与SESE关联较少,而且更多的是使代码撒谎.)
推荐阅读
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • JVM 学习总结(三)——对象存活判定算法的两种实现
    本文介绍了垃圾收集器在回收堆内存前确定对象存活的两种算法:引用计数算法和可达性分析算法。引用计数算法通过计数器判定对象是否存活,虽然简单高效,但无法解决循环引用的问题;可达性分析算法通过判断对象是否可达来确定存活对象,是主流的Java虚拟机内存管理算法。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • Java 11相对于Java 8,OptaPlanner性能提升有多大?
    本文通过基准测试比较了Java 11和Java 8对OptaPlanner的性能提升。测试结果表明,在相同的硬件环境下,Java 11相对于Java 8在垃圾回收方面表现更好,从而提升了OptaPlanner的性能。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
author-avatar
粉爱_粉爱陈小翔
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有