我尝试为 Java字节码实现几个静态分析.他们尝试计算某个方法是否具有特定的属性,例如是一种工厂方法.因为这些分析很难测试,所以我决定写一些Java代码,并用正确的属性直接注释方法.运行分析后,自动检查计算的和注释的属性是否相同是很容易的.

MyAnnotation:

@Retention(RUNTIME)
@Target(METHOD)
public @interface FactoryMethodProperty {

    FactoryMethodKeys value() default FactoryMethodKeys.NonFactoryMethod;
}

示例测试代码:

public class PublicFactoryMethod {

    private PublicFactoryMethod(){
        // I'm private
    }

    @FactoryMethodProperty
    public static void newInstanceAfterOtherConstructorCall(){
        new TransFacoryMethod();
        new PublicFactoryMethod();
    }

    @FactoryMethodProperty(FactoryMethodKeys.IsFactoryMethod)
    public static PublicFactoryMethod newInstance(){
        return new PublicFactoryMethod();
    }
}

因为我的测试代码中的大多数方法都不是工厂方法,所以我将默认值设置为枚举值“FactoryMethodKeys.NonFactoryMethod”.但是,当我没有将枚举值显式传递给注释时,它不会被编译为字节码.

字节码:

#23 = Utf8               value
  #24 = Utf8               Lorg/opalj/fpa/test/annotations/FactoryMethodKeys;
  #25 = Utf8               IsFactoryMethod

{
  public static void newInstanceAfterOtherConstructorCall();
    descriptor: ()V
    flags: ACC_PUBLIC,ACC_STATIC
    RuntimeVisibleAnnotations:
      0: #16()
    Code:
      stack=1,locals=0,args_size=0
         0: new           #17                 // class factoryMethodTest/TransFacoryMethod
         3: invokespecial #19                 // Method factoryMethodTest/TransFacoryMethod."<init>":()V
         6: new           #1                  // class factoryMethodTest/PublicFactoryMethod
         9: invokespecial #20                 // Method "<init>":()V
        12: return
      LineNumberTable:
        line 49: 0
        line 50: 6
        line 51: 12
      LocalVariableTable:
        Start  Length  Slot  Name   Signature

  public static factoryMethodTest.PublicFactoryMethod newInstance();
    descriptor: ()LfactoryMethodTest/PublicFactoryMethod;
    flags: ACC_PUBLIC,ACC_STATIC
    RuntimeVisibleAnnotations:
      0: #16(#23=e#24.#25)
    Code:
      stack=2,args_size=0
         0: new           #1                  // class factoryMethodTest/PublicFactoryMethod
         3: dup
         4: invokespecial #20                 // Method "<init>":()V
         7: areturn
      LineNumberTable:
        line 55: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
}

我错了什么?为什么默认值完全被忽略?

解决方法

它不需要在那里在运行时,JVM构造一个可以检索的注释实例.该实例将使用默认值进行初始化,该默认值在.class文件中,用于注释本身.这表示为 AnnotationDefault attribute

The AnnotationDefault attribute is a variable-length attribute in the
attributes table of certain method_info structures (§4.6),namely
those representing elements of annotation types. TheAnnotationDefault
attribute records the default value for the element represented by the
method_info structure.

Each method_info structure representing an element of an annotation
type may contain at most one AnnotationDefault attribute. The Java
Virtual Machine must make this default value available so it can be
applied by appropriate reflective APIs
.

你最终会调用注释实例的value()方法(或者你定义的任何其他方法),并返回该值.

Java注释的默认值是否被编译成字节码?的更多相关文章

  1. ios – Xamarin Ahead-of-Time(AOT)编译器与普通编译器

    我的理解是Xamarin的Ahead-of-Time编译器直接将Xamarin.iOS应用程序编译为本机ARM汇编代码.然而,我没有得到的是为什么它需要被称为“Ahead-of-Time”而不仅仅是一个普通的编译器.Xamarin的AOT编译器和传统编译器之间有什么区别,还是仅仅是一个营销术语?没有.Xamarin在该段中传达的信息是,他们的代码比简单的基于字节码的语言执行得更快.对于iOS和Android,他们都能够在热代码路径上执行本机代码以提高性能.AOT和JIT这两个术语是关于他们如何做到这一点的

  2. 使用swift编译器裸机?

    我真的很想使用swift进行嵌入式编程,因为我觉得它更适合用于c,我正在使用的处理器是ARMCortex-M4F(http://www.ti.com/tool/ek-tm4c123gxl).看一下swift编译器page,它说你可以从swift源生成LLVMIR然后我希望与LLVM交叉编译.这可能吗?绝对可以使用Swift生成机器代码.实际上,默认情况下,当您在Xcode或swiftc命令行编译器

  3. 什么是我可以使用Kotlin的最早的Android API级别?

    我认为这个问题很清楚但是我能在Kotlin上定位的最早API级别是什么?解决方法实际上,任何API级别.这是因为Kotlin被编译为JVM6平台的字节码,所有AndroidAPI级别都支持该字节码.因此,除非您在Kotlin代码中使用任何较新的AndroidAPI,否则它不需要任何特定的API级别.

  4. Kotlin与Android上的ART 100%兼容吗?

    ART是Android上的“新”Dalvik运行时版,自Android5.0起就取代了它.我非常热衷于Kotlin&在JVMv8上运行的JavaFX.我不确定Kotlin编译器生成或将在其达到v1.0发布状态时生成的字节码版本.所以问题是:ART现在能够运行“Kotlin代码”并且能够在未来运行Kotlin代码,例如什么时候Kotlin编译器要发出Java8字节码?解决方法与Android的兼容性是我们的首要任务,因此请确保Kotlin在发布时支持ART.目前Kotlin生成字节码版本1.6,因此它是兼容

  5. 详解Java中的字节码增强技术

    字节码增强技术就是一类对现有字节码进行修改或者动态生成全新字节码文件的技术。本文将通过示例详细说说Java的字节码增强技术,需要的可以参考一下

  6. 使用Android studio查看Kotlin的字节码教程

    这篇文章主要介绍了使用Android studio查看Kotlin的字节码教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  7. 详解JVM基础之字节码的增强技术

    字节码增强技术就是一类对现有字节码进行修改或者动态生成全新字节码文件的技术。接下来,我们将从最直接操纵字节码的实现方式开始深入进行剖析,感兴趣的可以了解一下

  8. Python字节码与程序执行过程详解

    这篇文章主要为大家介绍了Python字节码与程序执行过程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  9. java Class文件结构解析常量池字节码

    这篇文章主要为大家介绍了java Class文件的整体结构解析常量池字节码详细讲解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. Android逆向入门之常见Davlik字节码解析

    Dalvik是Google公司自己设计用于Android平台的虚拟机。Dalvik虚拟机是Google等厂商合作开发的Android移动设备平台的核心组成部分之一,本篇文章我们来详细解释常见Davlik字节码

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部