Reflection thoughts


#1

I know there's some work being done on reflection APIs, so perhaps this is premature, but I figured I'd toss out an issue and hopefully the reflection API will deal with it.

I love the data classes, and like to be able to declare a class as follows:

class SomeData(val id: String, val count: Int, val description: String)

I'd love to use these kinds of classes with reflection. For example, let's say I wanted to parse some JSON data into that data object:

{ "id": "abcdef",   "count": 24,   "description":"This is something"}

The problem is that I don't see how it can be done. In java, parameter names are not available via reflection. Now, I can get the names because under the hood, this class generates getters for id, count, and description. However, I can't tell what order they are in the constructor, and because they are immutable, there are no setters.

My current workaround is to use vars and a no-op constructor:

class SomeData {   var id: String? = null   var count: Int? = null   var description: String? = null }

This then generates setters for all of the values. Unfortunately, this is a little bit more clutter, plus, it renders properties that would normally be immutable (ie. id) as mutable, and thus, doesn't properly communicate what the object is all about.

I could also add annotations to all of the parameters, but that creates a ton more extra code that just repeats things that are already available.

My first thought would be to make parameter names available via a reflection API, or at least include an annotation that makes those available. There may be better ways.

I think the data classes have incredible usefulness (OR mapping obviously), but the reflection API will need to provide as much information as possible for them to be useful.


#2

The problem is that I don't see how it can be done. In java, parameter names are not available via reflection. ....

Actually javac -g:vars option generates parameter names in compiled class. So libraries like http://paranamer.codehaus.org/ are able to read the parameter names. I don't know if kotlinc also able to use -g option, maybe kotlin devs have an answer to this question.


#3

In fact, the kotlin compiler generates annotation info for every parameter, you can get them like this(Java code):

``

for(Method m : SomeKotlinClass.class.getMethods()){
           System.out.println(“nnn===”+m.getName());
           for(Annotation[] annots : m.getParameterAnnotations()){
                   System.out.println(“n”);
                   for(Annotation a : annots){
                   System.out.println(a.toString());
                   }
           }
  }

You will get something like this:

``

@jet.runtime.typeinfo.JetValueParameter(hasDefaultValue=false, typeProjections=[], receiver=false, nullable=false, type=?Ljava/lang/Class<+?Ljava/lang/Object;>;, name=oType)

@jet.runtime.typeinfo.JetValueParameter(hasDefaultValue=true, typeProjections=[], receiver=false, nullable=false, type=?Ljava/lang/reflect/Type;, name=genericType)

@jet.runtime.typeinfo.JetValueParameter(hasDefaultValue=false, typeProjections=[], receiver=false, nullable=false, type=?Ljavax/ws/rs/core/MediaType;, name=mediaType)

the last parameter of @JetValueParameter is “name”,  I think this is what you need.

Outersky


#4

Awesome. I'd seen that annotation, but wasn't sure about how reliable it would be in the future. Ipresume that this is something that will be documented as part of the standard API?


#5

Before Kotlin is released, we do not guarantee much about these annotations, when the binary format reaches a stable state it will be documented.