Annotation attribute must be a class literal? Why? Constants should be fine too

后端 未结 5 808
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-02-13 18:55

Can someone explain why String and Class annotation parameters are expected differently? Why does the compiler require literals for Classes, wherby accepting constants for Strin

相关标签:
5条回答
  • 2021-02-13 19:16

    I got the "annotation value must be a class literal" on the following:

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

    This happening whilst following one of Oracles tutorials on websockets. Turns out the video is not the 720p quality and the fuzziness hides the braces which look like curly brackets. So the error disappears upon changing brackets (parentheses) for braces.

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

    hth anyone who may trip over the same in the future.

    0 讨论(0)
  • 2021-02-13 19:18

    Room doesn't have a native support for storing dates, you need to convert it to LONG values while inserting and reading to and from the database. Hence we are responsible to instruct the Room database on how to convert the data.

    For that, thanks to room architecture, we have TypeConverter class. Well, don't get carried away, there isn't a special class that you can just extend and get things done, but its something you have to write from scratch but it does use Annotations to make it work with Room.

    For example, while dealing with 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();
        }
    }
    

    Now, we have to tell our Database class to use this TypeConverter Class using @TypeConverters (make sure to use plural version).

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

    You are ready to rock!

    0 讨论(0)
  • 2021-02-13 19:19
        maven {
            url 'https://maven.google.com'
        }
    

    You must paste this in your project build.gradle(Project: MyApplication(Project Name))

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

    You must paste this in your project build.gradle(Module:app)

    There might be a problem with dependency or just with their naming.

    If you want a full code example go for the link:

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

    0 讨论(0)
  • 2021-02-13 19:21

    The Java Language Specification doesn't permit you to use compile-time constants with parameters of type Class. You can only use class literals.

    The JLS has the following to say about suitable parameter values for annotations:

    An element type T is commensurate with an element value V if and only if one of the following conditions is true:

    • T is an array type E[] and either:
      • V is an ElementValueArrayInitializer and each ElementValueInitializer (analogous to a variable initializer in an array initializer) in V is commensurate with E. Or
      • V is an ElementValue that is commensurate with T.
    • The type of V is assignment compatible (§5.2) with T and, furthermore:
      • If T is a primitive type or String, V is a constant expression (§15.28).
      • V is not null.
      • if T is Class, or an invocation of Class, and V is a class literal (§15.8.2).
      • If T is an enum type, and V is an enum constant.

    It is a compile-time error if the element type is not commensurate with the ElementValue.

    I can't say why this restriction is in the JLS, however.

    0 讨论(0)
  • 2021-02-13 19:27

    Look this:

    public static final Class TEST_EXCEPTION = RuntimeException.class;
    

    The class should be a Throwable that the compiler is able to check. So, try this:

    public static final Class<? extends Throwable> TEST_EXCEPTION = RuntimeException.class;
    
    0 讨论(0)
提交回复
热议问题