堆栈跟踪中的神秘行

2024-02-22

While 调查堆栈跟踪差异 https://stackoverflow.com/questions/42462750/why-java-enum-need-to-check-class-and-declaringclass-in-compareto-method/42462851?noredirect=1#comment72068430_42462851在撰写另一个答案时,我遇到了一种我不理解的行为。考虑以下测试程序(这是我能缩小的范围):

interface TestInterface <U> {
    void test (U u);
}

static class Test <T extends Test<T>> implements TestInterface<T> { // line 11
    @Override public void test (T t) {
        throw new RuntimeException("My exception"); // line 13
    }
}

static class TestA extends Test<TestA> { }
static class TestB extends Test<TestB> { }

public static void main (String[] args) throws Exception {

    try {
        Test a = new TestA();
        Test b = new TestB();
        a.test(b);        
    } catch (Exception x) {
        x.printStackTrace(System.out);
    }

    try {
        TestInterface a = new TestA();
        Test b = new TestB();
        a.test(b);        
    } catch (Exception x) {
        x.printStackTrace(System.out);
    }

    try {
        TestInterface a = new TestA();
        TestInterface b = new TestB();
        a.test(b);        
    } catch (Exception x) {
        x.printStackTrace(System.out);
    }

}

第 11 行和第 13 行在上面的代码片段中被标记,并且可以在ideone上运行 http://ideone.com/y0THxm。该程序的输出是:

java.lang.RuntimeException: My exception
    at Ideone$Test.test(Main.java:13)
    at Ideone.main(Main.java:25)
java.lang.RuntimeException: My exception
    at Ideone$Test.test(Main.java:13)
    at Ideone$Test.test(Main.java:11)
    at Ideone.main(Main.java:33)
java.lang.RuntimeException: My exception
    at Ideone$Test.test(Main.java:13)
    at Ideone$Test.test(Main.java:11)
    at Ideone.main(Main.java:41)

我的问题是:为什么第二个和第三个测试用例的堆栈跟踪中显示第 11 行?三个测试用例之间的区别在于声明的类型a and b.

第 11 行(类声明行)仅在以下条件下出现:

  1. If Test实现一个接口,并且
  2. 如果异常是从接口方法抛出的,并且
  3. 如果接口采用类型参数,并且
  4. 如果类声明的类型参数包含extends Test<T>(如果第 11 行声明为class Test<T>), and
  5. 如果该方法被调用TestInterface类型而不是Test type.

注意到:

  • 这绝对是我抛出的异常(消息和堆栈跟踪)。
  • 如果我不抛出我的异常,则不会抛出其他异常。
  • 我已使用 Oracle JDK 1.7、Windows 上的 1.8 以及 Ideone 上的 1.8 重现了此内容。然而,1.7 在第 1 行而不是第 11 行包含一个堆栈跟踪元素(这非常奇怪)。

这里发生了什么?该行如何在堆栈跟踪中结束?如果两个对象都声明为,为什么它不会出现Test?

这是提示此问题的原始程序 http://ideone.com/5xmBHW,其中第 55 行java.lang.Enum存在如果a被声明为Comparable但当它被声明为时不存在Enum。第 55 行是声明Enum在 JDK 源代码中,第 180 行是显式抛出的ClassCastException.


您正在查看的效果桥接法 https://docs.oracle.com/javase/tutorial/java/generics/bridgeMethods.html!

The test中声明的方法TestInterface有擦除test(Object),但是test中声明的方法Test有擦除test(Test)。方法查找test(Object)方法找不到test(Test)方法,所以Java实际上把test(Object) and test(Test)中的方法Test的字节码。

您的第一次试用使用test(Test)方法,其行为如您所料。您的其他试验使用test(Object)方法,这是一个合成桥方法,只调用test(Test)方法。这个桥接方法实际上没有行号,因此它在堆栈跟踪中显示为相当任意的行号 11。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

堆栈跟踪中的神秘行 的相关文章

  • java 拖放

    我尝试熟悉java中的拖放 但我发现的所有教程都是 让我生气 我想要的只是从 JList 包含在名为 UserPanel 的自制 JPanel 中 拖动 PublicUserLabel 并将其放入从 JTabbedPanel 继承的自制类中
  • 在java代码中创建postgresql表

    我有一个与 postgreSQL 数据库连接的 java 代码 现在 我希望当它连接到数据库时 我还将创建数据库表 但我的问题是 它不会创建数据库 我不知道问题是什么 这是我的代码 Statement st null ResultSet r
  • Java 错误和警告列表

    在哪里 如何获得所有 java 和 javac 的错误和警告消息的列表 This http mindprod com jgloss compileerrormessages html我认为页面是您所需要的
  • JAX-WS 入门 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有人可以推荐一些关于 JAX WS 入门的好教程吗 使用各种工具 如 wsgen 等 您可以从这里开始 通过 Java SE 6 平台介绍
  • Spring Data Jpa OneToMany 同时保存子实体和父实体?

    这是我的父实体 注意 为了简洁起见 删除了 getter setter lombok 注释 Entity public class Board Id GeneratedValue strategy GenerationType IDENTI
  • 是否可以使用 Apache Tika 提取表信息?

    我正在寻找 pdf 和 MS Office 文档格式的解析器 以从文件中提取表格信息 当我看到 Apache Tika 时 正在考虑编写单独的实现 我能够从任何这些文件格式中提取全文 但我的要求是提取表格数据 我希望有 2 列采用键值格式
  • 如何使用 aether 从 Java 找到最新版本的 Maven 工件?

    他们的文档非常薄弱 我无法弄清楚 我找到了部分答案here https stackoverflow com questions 27428068 how to retrieve the latest also snapshot versio
  • java:为什么主线程等待子线程完成

    我有一个简单的java程序 主线程 main 创建并启动另一个线程t class T extends Thread Override public void run while true System out println Inside
  • 生成一定长度的所有排列

    假设我们有一个字母表 abcdefghiklimnop 如何以有效的方式以五个一组的形式重复该字母表来递归生成排列 几天来我一直在为此苦苦挣扎 任何反馈都会有帮助 本质上这与 生成给定字符串的所有排列 https stackoverflow
  • java彩色滚动条搜索结果

    我将如何在 Java 中自定义滚动条 以便我可以进行像 chrome 一样的搜索 也就是说在结果所在的位置放置彩色条纹 我不想要一个库 因为我更喜欢自己编写代码 另外 我不想失去我拥有的 L F 欢迎举例 实际上 它将查看一个大的文本文件或
  • java绕中心旋转矩形

    我想围绕其中心点旋转一个矩形 它应该保留在应该绘制的位置并在该空间中旋转 这是我的代码 AffineTransform transform new AffineTransform transform rotate Math toRadian
  • React Native v0.71.8 React-native-vector-icons 你看不到的图标

    我在用react native版本v0 71 8 我安装了react native vector icons库 但图标未显示 似乎链接在最新版本的 React Native 中不再起作用 所以我按照说明进行操作 但它不再编译 出现以下错误
  • 在约束验证器中使用 Guice 进行依赖注入

    我有一个在 ConstraintValidator 的实现中注入类的用例 我正在使用 Google guice 进行依赖项注入 目前无法在验证器内注入 我的场景的简化形式 内部模块 Provides Singleton public Ser
  • 在 Eclipse RCP 应用程序中禁用插件贡献

    我经常遇到这个问题 但尚未找到解决方案 每当我编写一个新的基于 Eclipse RCP 的应用程序并包含来自 Eclipse 平台的插件时 我都会 继承 其中一些插件的 UI 贡献 大多数贡献 菜单项 键盘快捷键 属性页 都很有用 但有时我
  • 在 Kotlin 中声明静态属性?

    My Java code public class Common public static ModelPengguna currentModelPengguna public class Common companion object v
  • 如何使用 AffineTransform.quadrantRotate 旋转位图?

    我想旋转一个bitmap关于它的中心点 然后将其绘制成更大的图形上下文 位图是40x40 pixels 图形上下文是500x500 pixels 这就是我正在做的 BufferedImage bi new BufferedImage 500
  • log4j.properties 在 Wildfly 上无法正常工作

    我的类路径中有一个 log4j properties 文件 它位于 APP XX jar log4j properties 位置 我注意到在ear文件中我还可以在lib文件夹中找到log4j 1 2 17 jar 但无论我在 log4j p
  • 在 Spring MVC 中将请求写入文件

    我希望能够将整个请求写入 Spring MVC 控制器中的文件 我已尝试以下操作 但即使我使用大量参数发出 POST 请求 文件也始终为空 RequestMapping method RequestMethod POST value pay
  • 如何更改 JAX-WS Web 服务的地址位置

    我们目前已经公开了具有以下 URL 的 JAX RPC Web 服务 http xx xx xx xx myservice MYGatewaySoapHttpPort wsdl http xx xx xx xx myservice MYGa
  • junit4 使用特定测试方法创建测试套件

    在 junit4 中 我想执行来自不同类的特定测试方法 即想要使用来自不同类的特定测试方法创建一个测试套件 假设我有两门课 public class Test Login Test public void test Login 001 Sy

随机推荐