当前位置: 首页 > 知识库问答 >
问题:

是否可以通过字节码定义方法绑定类型?

钦景胜
2023-03-14

来自以下来源:

https://www.amazon.com/java-complete-reference-herbert-schildt/dp/0071808558

第8章:在继承中使用final

对于私有、静态、最终方法,应该使用早期(静态)方法绑定

class MethodRefDemo2
{
  public static void main( String args[] )
  {
    BindingTest bindingTest = new BindingTest();
    bindingTest.printEarly();
    bindingTest.printLate();
  }
}

class BindingTest
{
  private String early = "static";
  private String late = "dynamic";

  final String printEarly()
  {
    return early;
  }

  String printLate()
  {
    return late;
  }
}

所以正如我所认为的,这两个方法应该有不同的绑定类型。检查字节码:

 public static main([Ljava/lang/String;)V
   L0
    LINENUMBER 8 L0
    NEW spring/BindingTest
    DUP
    INVOKESPECIAL spring/BindingTest.<init> ()V
    ASTORE 1
   L1
    LINENUMBER 9 L1
    ALOAD 1
    INVOKEVIRTUAL spring/BindingTest.printEarly ()Ljava/lang/String;
    POP
   L2
    LINENUMBER 10 L2
    ALOAD 1
    INVOKEVIRTUAL spring/BindingTest.printLate ()Ljava/lang/String;
    POP
   L3
    LINENUMBER 11 L3
    RETURN
   L4
    LOCALVARIABLE args [Ljava/lang/String; L0 L4 0
    LOCALVARIABLE bindingTest Lspring/BindingTest; L1 L4 1
    MAXSTACK = 2
    MAXLOCALS = 2

在这里我看到了两个有害的指示。那么有什么方法可以确定类字节码使用了哪种绑定呢?如果没有,如何确定绑定类型?

共有1个答案

陶宏浚
2023-03-14

短语“来自java规范”是误导性的,因为没有多个规范,所以只有不包含引用语句的java规范。

术语“早期绑定”和“后期绑定”不足以描述Java方法调用的可能性。

>

  • 在编译时解析最终目标的唯一方法调用是private方法和构造函数调用,以及自Java8以来,interface类型上的static方法调用。

    当接收者类型是接口时,在编译时永远不能将其视为final,但在运行时仍以final方法结束。

    当然,在解析之后,JVM可能会注意到目标方法已经声明final,并转向与上面第二种“早期绑定”相匹配的优化调用,另一方面,大多数JVM足够聪明,可以对尚未声明final但仍未实际重写的方法执行相同的操作(这可能适用于大多数方法)。因此,将final方法的调用称为“早期绑定”是毫无意义的,如果唯一的结果是同时应用于其他方法的优化。

  •  类似资料:
    • 问题内容: 在JavaScript中使用构造函数创建类时,以后是否可以重新定义类的方法? 例: 现在,我想像这样重新定义: 因此,当我创建另一个时,新方法将被称为: 编辑: 我意识到我可以输入“ Hello”或“Hola”之类的参数来完成不同的输出。我还意识到我可以像这样简单地为p2分配一个新函数: 我只是想知道是否可以重新定义类的方法,以便的新实例将使用新方法。 问题答案: 以后可以重新定义类的

    • 上下文 我有一个基于OSGi的大型(Equinox3.9/EclipseRCP4.4)应用程序,还有几个“可选”包。这些可选捆绑包中的每一个都提供了可选的用户界面和一些额外的服务(通过SCR组件),这些服务只适用于我们的一部分客户。 应用程序始终作为预打包安装分发(也就是说,我们不使用P2或任何其他自动配置机制)。直到最近,我们为每个需要一些可选捆绑包的客户构建了不同的预打包安装。可选捆绑包的数量

    • 问题内容: 我有一些需要经常打印的结构。现在,我正在围绕该结构使用经典的打印包装器: 此功能很方便,但实际上也很有限。如果不进行新包装,则无法添加或添加一些文本。我知道我可以使用 va_arg 系列添加或添加一些文本,但是我觉得我会重新实现。 我想知道是否有可能向printf编写自定义函数。我希望能够写这样的东西: 这可能吗 ?我怎样才能做到这一点 ? 注意:我在Ubuntu Linux 10.0

    • 我有两个portlet:Portlet-A和Portlet-B。 Portlet-A进行一些数据初始化并将其存储在共享范围内。 Portlet-B在初始化期间需要来自共享范围的数据(来自Portlet-A)。 然而,我需要定义Portlet-A必须在Portlet-B之前启动(呈现)。 Liferay是否可以定义一些初始化顺序,或者类似于portlet依赖关系的东西?

    • 我有一个基于Spring Boot的库(使用spring-data-mongo),它创建了一个bean。碰巧实现了

    • 问题内容: 我正在使用一个API,该API需要额外的安全性信息以及HTTP请求作为标头中的元信息发送。是否可以在XMLHttpRequest中设置它们? 问题答案: 是的,请参阅2012年12月6日当前XMLHttpRequest工作草案的“ setRequestHeader()方法” 。