【问题标题】:How to calculate bridge method target如何计算桥接法目标
【发布时间】:2010-02-04 06:04:03
【问题描述】:

泛型为 java 带来了很多好处,但它们也意味着麻烦,因为引入了桥接方法,这意味着很难找到给定名称和目标的方法,因为擦除和桥接方法意味着客户端实际上使用桥接而不是比目标。

方法的返回类型已被省略,因为它们对于这个问题并不重要...

class Super{
}

class Sub extends Super{
}

interface Interface<T extends Super>{
   method( T t ); // erased -> method( Super super );
}

interface Interface2 extends Interface<T extends Sub>{
   method2( T t ); // erased -> method2( Sub sub );
}

class Concrete implements Interface2{
   method( Sub sub );     // erased to method( Super super);
   method2( Sub sub );
}

我如何以编程方式确定 Concrete.method(Super) 最终调用 Concrete.method(Sub) ?我想避免基于参数化类型的计算,因为这会很快变得复杂......

我看过 Springs BridgeMethodResolver,但它相当复杂,而且做了很多事情,肯定有更简单的方法..也许没有..

【问题讨论】:

    标签: java methods


    【解决方案1】:

    我想到的是:

    • 找到方法参数的所有可能变体,(使用.getSuperclass())最后一个是(Object, Object, ...)
    • 遍历所有这些并找到不是Method.isBridge()的那个;

    但这又是太多的工作,它可能不起作用:)。我建议这样做:

    Method target = new BridgeMethodResolver().findBridgedMethod(bridgedMethod);
    

    无论有什么复杂性,它对你来说都是隐藏的。

    如果你不想依赖 spring,只需复制粘贴该类的代码即可。

    【讨论】:

    • 使用 getSuperClass 然后测试 isBridge() 并不是很准确,应该真的使用参数化类型等,但这很复杂。 BMR 似乎做了很多猜测,一个人知道一种方法是一座桥梁,但又不能轻易问它的桥梁是什么,这似乎不是很疯狂......
    • 无法复制/粘贴 Spring BMR,因为它具有复杂的 spring 依赖关系图。我还必须验证它是否可以处理带有类型变量行走的接口。你的反射行走的东西是行不通的,实际上需要抓取类型变量和它们的值,然后走上图表并跟踪这些变量并匹配它们。
    • @mP - 不,该类没有复杂的依赖关系图。它只依赖于两个实用程序类,而这两个实用程序类又不依赖于 JavaSE 以外的任何东西
    【解决方案2】:

    faced 一个相关问题 - 我需要检索“原始”方法的注释,但由于桥(没有注释),很难找到该方法。我最终提交了一个被接受的enhancement request。在您的情况下,我不知道您需要该方法的用途,因此不幸的是,该请求(现在已制定)可能对您没有帮助。

    【讨论】:

    • 我正在用 ASM 编写一个拦截器,我的选择器之一是按类型,所以我只能找到返回类型为 X 的方法。根据我上面的示例,超类永远不会有一个 X 在它的签名中,即使在源代码中它看起来像因为类型变量。因此,当通过查看看起来它们应该匹配的源时跳过/忽略该方法是错误的。
    • 您的示例具有通用方法参数,而不是返回类型,所以我有点困惑。如果它是返回类型 - 它们在 Java 中是协变的:子类可以覆盖返回 X 的超类型的方法以返回 X。因此假设您的选择器可以接受所有返回 X 的超类型的方法,然后您也不会有过桥问题。
    猜你喜欢
    • 2016-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多