13

有人可以解释为什么 String 和 Class 注释参数的预期不同吗?为什么编译器需要类的文字,而同时接受字符串的常量?

使用 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 常量但只接受类文字?

4

5 回答 5

10

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

JLS对注释的合适参数值有以下说法:

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

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

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

但是,我不能说为什么 JLS 中有这个限制。

于 2011-12-22T15:58:40.277 回答
2

我在以下内容中得到“注释值必须是类文字”:

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

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

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

hth 任何可能在未来绊倒的人。

于 2014-02-21T21:48:21.450 回答
0

看看这个:

public static final Class TEST_EXCEPTION = RuntimeException.class;

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

public static final Class<? extends Throwable> TEST_EXCEPTION = RuntimeException.class;
于 2011-12-22T13:27:48.063 回答
0

Room 没有对存储日期的原生支持,您需要在向数据库插入和读取数据库时将其转换为 LONG 值。因此,我们负责指导 Room 数据库如何转换数据。

为此,由于房间架构,我们有TypeConverter类。好吧,不要得意忘形,没有一个特殊的类可以扩展并完成工作,但它是你必须从头开始编写的东西,但它确实使用 Annotations 使其与 Room 一起工作。

例如,在处理 Dates 时:

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();
    }
}

现在,我们必须通过@TypeConverters告诉我们的 Database 类使用这个 TypeConverter 类(确保使用复数版本)。

@Database(entities = {Entity.class}, version = 1)
@TypeConverters(DateConverter.class)
public abstract class AppDatabase extends RoomDatabase {...}    

你准备好摇滚了!

于 2018-11-24T07:21:18.690 回答
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

于 2019-05-14T04:33:09.743 回答