Reflection thoughts

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.

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.

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

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?

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