3

What would be the equivalent of the following annotation usage in kotlin:

@TypeDefs({
        @TypeDef(name = "string-array", typeClass = StringArrayType.class),
        @TypeDef(name = "int-array", typeClass = IntArrayType.class),
        @TypeDef(name = "json", typeClass = JsonStringType.class),
        @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
})

This is the definition of @TypeDefs

@Target({TYPE, PACKAGE})
@Retention(RUNTIME)
public @interface TypeDefs {
    /**
     * The grouping of type definitions.
     */
    TypeDef[] value();
}
public class Foo {...}

and this is the one of @TypeDef

@Target({TYPE, PACKAGE})
@Retention(RUNTIME)
@Repeatable(TypeDefs.class)
public @interface TypeDef {
    /**
     * The type name.  This is the name that would be used in other locations.
     */
    String name() default "";

    /**
     * The type implementation class.
     */
    Class<?> typeClass();

    /**
     * Name a java type for which this defined type should be the default mapping.
     */
    Class<?> defaultForType() default void.class;

    /**
     * Any configuration parameters for this type definition.
     */
    Parameter[] parameters() default {};
}

I tried using arrayOf() but it's not working.

@TypeDefs(arrayOf(
        @TypeDef(name = "string-array", typeClass = StringArrayType::class),
        @TypeDef(name = "int-array", typeClass = IntArrayType::class),
        @TypeDef(name = "json", typeClass = JsonStringType::class),
        @TypeDef(name = "jsonb", typeClass = JsonBinaryType::class)
))
data class Foo (...)

I'm getting the following error on IntelliJ Idea: An annotation cannot be used as the annotations argument

JaviOverflow
  • 1,434
  • 2
  • 14
  • 31
  • What code did you write that didn't work? Also, perhaps this answer can help you: https://stackoverflow.com/a/49414616/4465208 – zsmb13 Aug 08 '18 at 19:06
  • @zsmb13 updated my question with the code I tried. Okay that question helped me, it's about taking off the @ and using named arguments. Thanks!! – JaviOverflow Aug 08 '18 at 19:12

2 Answers2

5

I had to do the following to make it work:

  • Take off the @ from inner annotations
  • Wrap the list with arrayOf
  • Pass the array as named argument.

Here is the working code:

@TypeDefs(value = arrayOf(
        TypeDef(name = "string-array", typeClass = StringArrayType::class),
        TypeDef(name = "int-array", typeClass = IntArrayType::class),
        TypeDef(name = "json", typeClass = JsonStringType::class),
        TypeDef(name = "jsonb", typeClass = JsonBinaryType::class)
))
data class Line(...)

alternatively one can also use square brackets instead of arrayOf:

@TypeDefs(value = [
    TypeDef(name = "string-array", typeClass = StringArrayType::class),
    TypeDef(name = "int-array", typeClass = IntArrayType::class),
    TypeDef(name = "json", typeClass = JsonStringType::class),
    TypeDef(name = "jsonb", typeClass = JsonBinaryType::class)
])
data class Line(...)

UPDATE: Based on @Zoe's answer

If the only argument is the annotation list, you don't need to specify the named argument and it gets simplified as:

@TypeDefs(
    TypeDef(name = "string-array", typeClass = StringArrayType::class),
    TypeDef(name = "int-array", typeClass = IntArrayType::class),
    TypeDef(name = "json", typeClass = JsonStringType::class),
    TypeDef(name = "jsonb", typeClass = JsonBinaryType::class)
)
data class Line(...)
JaviOverflow
  • 1,434
  • 2
  • 14
  • 31
3

If you use the Convert file to Kotlin tool in IntelliJ, the annotation gets converted to:

@TypeDefs(
    TypeDef(name = "string-array", typeClass = StringArrayType::class), 
    TypeDef(name = "int-array", typeClass = IntArrayType::class), 
    TypeDef(name = "json", typeClass = JsonStringType::class), 
    TypeDef(name = "jsonb", typeClass = JsonBinaryType::class)
)
data class Foo(...)

Seems to do the same as using value = arrayOf(...), as JaviOverflow mentioned.


If you would like to use arrayOf or [] instead you will need to use something like this but it is redundant asterisk * is just spread operator:

@TypeDefs(
    *arrayOf(
        TypeDef(name = "string-array", typeClass = StringArrayType::class),
        ...
    )
)

@TypeDefs(
    *[
        TypeDef(name = "string-array", typeClass = StringArrayType::class),
        ...
    ]
)

Otherwise you will get type mismatch.

GROX13
  • 4,605
  • 4
  • 27
  • 41
Zoe
  • 27,060
  • 21
  • 118
  • 148