注释属性必须是类文字?为什么?常数也应该没问题

时间:2011-12-22 13:09:25

标签: java testng jls

有人可以解释为什么String和Class注释参数的预期不同吗?为什么编译器需要Classes的文字,wherby也接受Strings的常量?

Spring的@RequestMapping工作示例:

public class MyController {
    public static final String REQUEST_MAPPING = "/index.html";
    @RequestMapping(MyController.REQUEST_MAPPING) // ALL OK!
    ...
}

使用TestNG的@Test的WTF示例:

public class MyControllerTest {
    public static final Class TEST_EXCEPTION = RuntimeException.class;
    @Test(expectedExceptions = MyControllerTest.TEST_EXCEPTION) // compilation error, WTF:
    // The value for annotation attribute Test.expectedExceptions must be a class literal
    ...
}

当然,工作是@Test(expectedExceptions = RuntimeException.class)。但为什么?我看到的注释参数的唯一区别是它的类型:String vs Class。为什么Java编译器也会接受String常量,但只接受类文字?

5 个答案:

答案 0 :(得分:8)

Java语言规范不允许您使用类型为Class的参数的编译时常量。你只能使用类文字。

JLS有关于注释的合适参数值的以下内容:

  

当且仅当下列条件之一为真时,元素类型 T 才与元素值 V 相称:

     
      
  • T 是一个数组类型 E [] ,并且:   
        
    • V 是一个 ElementValueArrayInitializer V 中的每个 ElementValueInitializer (类似于数组初始值设定项中的变量初始值设定项) >与 E 相称。或者
    •   
    • V ElementValue ,与 T 相称。
    •   
  •   
  • V 的类型与 T 分配兼容(§5.2),此外:   
        
    • 如果 T 是基本类型或字符串,则 V 是常量表达式(§15.28)
    •   
    • V 不为空。
    •   
    • 如果 T 是Class,或者是Class的调用,而V是类文字(§15.8.2)
    •   
    • 如果 T 是枚举类型, V 是枚举常量。
    •   
  •   
     

如果元素类型与 ElementValue 不相符,则为编译时错误。

但我不能说为什么这个限制在JLS中。

答案 1 :(得分:2)

我得到了#34;注释值必须是一个类文字"以下内容:

@ServerEndpoint(value="/story/notifications",
        encoders = (StickerEncoder.class),
        decoders = (StickerDecoder.class))

这是在关于websockets的Oracles教程之后发生的。原来视频不是720p的质量,模糊隐藏了看起来像花括号的大括号。因此,更改大括号的括号(括号)时错误消失。

@ServerEndpoint(value="/story/notifications",
        encoders = {StickerEncoder.class},
        decoders = {StickerDecoder.class})

任何可能在将来绊倒的人。

答案 2 :(得分:0)

看看这个:

public static final Class TEST_EXCEPTION = RuntimeException.class;

该类应该是编译器能够检查的Throwable。所以,试试这个:

public static final Class<? extends Throwable> TEST_EXCEPTION = RuntimeException.class;

答案 3 :(得分:0)

Room不支持存储日期 ,您需要在插入数据库和从数据库读取数据时将其转换为LONG值。因此,我们有责任指导Room数据库如何转换数据。

为此,由于房间结构的原因,我们有了 TypeConverter 类。好吧,别被迷住了,没有一个特殊的类可以扩展并完成工作,但是您必须从头开始编写它,但是它确实使用了Annotations使其可以与Room一起使用。

例如,在处理日期时:

var oneDArray = function(weekArray){

  var week = []; 
  for(var  i=0; i< weekArray.length;i++){
        var conDays = weekArray[i];
        if((sorter[conDays[1]] - sorter[conDays[0]]) === 0 ){
            week[i] = conDays[0];
        }
        else if((sorter[conDays[1]] - sorter[conDays[0]]) === 1 ){
            week[i] = conDays;
        }else{
            week[i] = conDays.join("-");
        } 
  }
  return week.join();
};

var convertToWeekRanges = function (week) {
       var weekRanges = [] 
       weekRanges[0] = [week[0], week[0]];
       var  lastIndex = 0;

    for (var i = 1; i < week.length; i++) {

        if ((sorter[week[i]] - sorter[weekRanges[lastIndex][1]]) === 1) {
            weekRanges[lastIndex][1] = week[i];
        } else {
            weekRanges[++lastIndex] = [week[i], week[i]];
        }
    }
    return weekRanges;
};

console.log(oneDArray(convertToWeekRanges(['MON','TUE'] )));

console.log(oneDArray(convertToWeekRanges(['MON','TUE','WED','THU','SAT','SUN'])));

console.log(oneDArray(convertToWeekRanges(['MON','TUE','WED','THU','FRI','SUN'])));

现在,我们必须通过 @TypeConverters (确保使用复数版本)来告诉数据库类使用此TypeConverter类。

import android.arch.persistence.room.TypeConverter;
import java.util.Date;

//Type-Converter Class for Room
public class DateConverter {
    @TypeConverter
    // Long value to Date value
    public static Date toDate(Long timestamp) {
        return timestamp == null ? null : new Date(timestamp);
    }

    @TypeConverter
    // Date value to Long value
    public static Long toTimestamp(Date date) {
        return date == null ? null : date.getTime();
    }
}

您准备好摇滚了!

答案 4 :(得分:0)

    maven {
        url 'https://maven.google.com'
    }

您必须将此粘贴到您的项目build.gradle(Project:MyApplication(Project Name))

implementation 'android.arch.persistence.room:runtime:1.1.1'
annotationProcessor 'android.arch.persistence.room:compiler:1.1.1'

您必须将此粘贴到您的项目build.gradle(Module:app)

依赖性或名称可能有问题。

如果您想要完整的代码示例,请转到链接:

https://www.captechconsulting.com/blogs/android-architecture-components-room-persistence-library

相关问题