java8-注释比较<;T>;具有可比性<;T>;将注释添加到compareTo(对象o)

java8-注释比较<;T>;具有可比性<;T>;将注释添加到compareTo(对象o),java,annotations,java-8,Java,Annotations,Java 8,我有一个注解 package javaannotationtest; import java.lang.annotation.*; @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface CustomAnnotation { } 这将应用于以下类中的compareTo package javaannotationtest; public class Customer imple

我有一个注解

package javaannotationtest;

import java.lang.annotation.*;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {
}
这将应用于以下类中的compareTo

package javaannotationtest;

public class Customer implements Comparable<Customer>{
    @Override
    @CustomAnnotation
    public int compareTo(Customer o) {
        return 0;
    }
}
请注意,compareTo(对象)没有注释。

爪哇8

1.8.0 -> public int javaannotationtest.Customer.compareTo(javaannotationtest.Customer)
 has  annotation of type javaannotationtest.CustomAnnotation
1.8.0 -> public int javaannotationtest.Customer.compareTo(java.lang.Object)
 has  annotation of type javaannotationtest.CustomAnnotation
Java8在
compareTo(Java.lang.Object)
方法中添加了注释

下面是使用Java8编译的版本的javap输出(可能不相关,它显示了添加到这两个方法中的注释)

Classfile/C:/code/java8annoation/out/production/java8annoation/javaannoationtest/Customer.class
最后修改日期:2014年4月17日;大小719字节
MD5校验和678e0371f5f9ed5666b513c940f365a7
从“Customer.java”编译而来
公共类javaannotationtest.Customer扩展了java.lang.Object实现了java.lang.Test
签名:#20//Ljava/lang/Object;Ljava/lang/Comparable;
源文件:“Customer.java”
次要版本:0
主要版本:52
旗帜:ACC_公共、ACC_超级
固定池:
#1=Methodref#4.#23//java/lang/Object.“:()V
#2=类#24//javaannotationtest/客户
#3=Methodref#2.#25//javaannotationtest/Customer.compareTo:(Ljavaannotationtest/Customer;)I
#4=类#26//java/lang/Object
#5=类#27//java/lang/Comparable
#6=Utf8
#7=Utf8()V
#8=Utf8代码
#9=Utf8行号表
#10=Utf8 LocalVariableTable
#11=Utf8此
#12=Utf8 Ljavaannotationtest/客户;
#13=Utf8比较到
#14=Utf8(Ljavaannotationtest/Customer;)I
#15=Utf8 o
#16=Utf8运行时访问说明
#17=Utf8 Ljavaannotationtest/CustomAnnotation;
#18=Utf8(Ljava/lang/Object;)I
#19=Utf8签名
#20=Utf8 Ljava/lang/Object;Ljava/lang/Comparable;
#21=Utf8源文件
#22=Utf8 Customer.java
#23=名称和类型#6:#7/“”:()V
#24=Utf8 javaannotationtest/客户
#25=名称和类型#13:#14//比较到:(Ljavaannotationtest/Customer;)I
#26=Utf8 java/lang/Object
#27=Utf8 java/lang/Compariable
{
public javaannotationtest.Customer();
描述符:()V
旗帜:ACC_PUBLIC
代码:
堆栈=1,局部变量=1,参数大小=1
0:aload_0
1:invokespecial#1//方法java/lang/Object。“:()V
4:返回
LineNumberTable:
第3行:0
LocalVariableTable:
起始长度插槽名称签名
0 5 0此Ljavaannotationtest/客户;
public int compareTo(javaannotationtest.Customer);
描述符:(Ljavaannotationtest/Customer;)I
旗帜:ACC_PUBLIC
代码:
堆栈=1,局部变量=2,参数大小=2
0:iconst_0
1:我轮到你了
LineNumberTable:
第7行:0
LocalVariableTable:
起始长度插槽名称签名
0 2 0此Ljavaannotationtest/客户;
0 2 1 o Ljavaannotationtest/客户;
运行时访问说明:
0: #17()
public int compareTo(java.lang.Object);
描述符:(Ljava/lang/Object;)I
标志:ACC_公共、ACC_桥、ACC_合成
代码:
堆栈=2,局部变量=2,参数大小=2
0:aload_0
1:aload_1
2:checkcast#2//class javaannotationtest/Customer
5:invokevirtual#3//方法比较:(Ljavaannotationtest/Customer;)I
8:我轮到你了
LineNumberTable:
第3行:0
LocalVariableTable:
起始长度插槽名称签名
0 9 0此Ljavaannotationtest/客户;
运行时访问说明:
0: #17()
}

有人能解释一下Java8中的相关变化吗?(在符合条件时将提供赏金)。

本期中描述了这一变化。关于这个特性似乎没有太多的讨论,但是请求和理由对我来说是有意义的

请求的说明: 当一个类扩展了一个泛型类或实现了一个泛型接口时,由于擦除的原因,可能会生成一个合成方法,在采用特定参数/返回的方法和用对象定义的超类/接口之间架起桥梁。根据Java语言规范,桥接方法将调用重定向到实际方法。但是,桥接方法缺少为原始方法及其参数定义的注释

理由: 当试图在运行时检索此类方法的注释时,会出现问题。因为不可能可靠地找出哪些类替换了泛型参数,所以我们不知道要将哪个参数发送到getMethod(…)以接收正确的方法。当发送Object.class(而泛型参数是另一个类)时,getMethod将返回bridge方法,该方法将不包含有关原始方法注释的信息

还记录在以下文件中:

区域:工具/javac

简介
从本版本开始,参数和方法注释被复制到合成桥方法。此修复意味着现在对于以下程序:

@Target(value = {ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@interface ParamAnnotation {}
 
@Target(value = {ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MethodAnnotation {}
 
abstract class T<A,B> {
    B m(A a){return null;}
 }
 
 class CovariantReturnType extends T<Integer, Integer> {
     @MethodAnnotation
     Integer m(@ParamAnnotation Integer i) {
         return i;
     }
 
    public class VisibilityChange extends CovariantReturnType {}
 
}
@Target(值={ElementType.PARAMETER})
@保留(RetentionPolicy.RUNTIME)
@接口参数{}
@目标(值={ElementType.METHOD})
@保留(RetentionPolicy.RUNTIME)
@接口方法注释{}
抽象类T


@卡普:回答得很好。我想补充一些关于这个问题的补充资料。不仅注释被复制到bridg
  Classfile /C:/code/java8annoation/out/production/java8annoation/javaannotationtest/Customer.class
  Last modified 17 Apr, 2014; size 719 bytes
  MD5 checksum 678e0371f5f9ed5666b513c940f365a7
  Compiled from "Customer.java"
public class javaannotationtest.Customer extends java.lang.Object implements java.lang.Comparable<javaannotationtest.Customer>
  Signature: #20                          // Ljava/lang/Object;Ljava/lang/Comparable<Ljavaannotationtest/Customer;>;
  SourceFile: "Customer.java"
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #4.#23         //  java/lang/Object."<init>":()V
   #2 = Class              #24            //  javaannotationtest/Customer
   #3 = Methodref          #2.#25         //  javaannotationtest/Customer.compareTo:(Ljavaannotationtest/Customer;)I
   #4 = Class              #26            //  java/lang/Object
   #5 = Class              #27            //  java/lang/Comparable
   #6 = Utf8               <init>
   #7 = Utf8               ()V
   #8 = Utf8               Code
   #9 = Utf8               LineNumberTable
  #10 = Utf8               LocalVariableTable
  #11 = Utf8               this
  #12 = Utf8               Ljavaannotationtest/Customer;
  #13 = Utf8               compareTo
  #14 = Utf8               (Ljavaannotationtest/Customer;)I
  #15 = Utf8               o
  #16 = Utf8               RuntimeVisibleAnnotations
  #17 = Utf8               Ljavaannotationtest/CustomAnnotation;
  #18 = Utf8               (Ljava/lang/Object;)I
  #19 = Utf8               Signature
  #20 = Utf8               Ljava/lang/Object;Ljava/lang/Comparable<Ljavaannotationtest/Customer;>;
  #21 = Utf8               SourceFile
  #22 = Utf8               Customer.java
  #23 = NameAndType        #6:#7          //  "<init>":()V
  #24 = Utf8               javaannotationtest/Customer
  #25 = NameAndType        #13:#14        //  compareTo:(Ljavaannotationtest/Customer;)I
  #26 = Utf8               java/lang/Object
  #27 = Utf8               java/lang/Comparable
{
  public javaannotationtest.Customer();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0       
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return        
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Ljavaannotationtest/Customer;

  public int compareTo(javaannotationtest.Customer);
    descriptor: (Ljavaannotationtest/Customer;)I
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=2, args_size=2
         0: iconst_0      
         1: ireturn       
      LineNumberTable:
        line 7: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       2     0  this   Ljavaannotationtest/Customer;
            0       2     1     o   Ljavaannotationtest/Customer;
    RuntimeVisibleAnnotations:
      0: #17()

  public int compareTo(java.lang.Object);
    descriptor: (Ljava/lang/Object;)I
    flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0       
         1: aload_1       
         2: checkcast     #2                  // class javaannotationtest/Customer
         5: invokevirtual #3                  // Method compareTo:(Ljavaannotationtest/Customer;)I
         8: ireturn       
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0  this   Ljavaannotationtest/Customer;
    RuntimeVisibleAnnotations:
      0: #17()
}
@Target(value = {ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@interface ParamAnnotation {}
 
@Target(value = {ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MethodAnnotation {}
 
abstract class T<A,B> {
    B m(A a){return null;}
 }
 
 class CovariantReturnType extends T<Integer, Integer> {
     @MethodAnnotation
     Integer m(@ParamAnnotation Integer i) {
         return i;
     }
 
    public class VisibilityChange extends CovariantReturnType {}
 
}
public int compareTo(Customer);
descriptor: (LCustomer;)I
flags: ACC_PUBLIC
Code:
  stack=1, locals=2, args_size=2
     0: iconst_0      
     1: ireturn       
  LineNumberTable:
    line 11: 0
MethodParameters:
  Name                           Flags
  o                              
RuntimeVisibleAnnotations:
  0: #15()

public int compareTo(java.lang.Object);
descriptor: (Ljava/lang/Object;)I
flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
Code:
  stack=2, locals=2, args_size=2
     0: aload_0       
     1: aload_1       
     2: checkcast     #2                  // class Customer
     5: invokevirtual #3                  // Method compareTo:(LCustomer;)I
     8: ireturn       
  LineNumberTable:
    line 7: 0
MethodParameters:
  Name                           Flags
  o                              synthetic  <-- see the name copied to the bridge method
RuntimeVisibleAnnotations:
  0: #15()