so, im doing a bit of premature optimization: im w...
# compiler
g
so, im doing a bit of premature optimization: im writing some kotlin wrappers for guice methods used by a large java codebase. I'm looking to streamline the
getInstance
flow. Im looking at something like this:
Copy code
inline fun <reified T> Injector.getInstance(): T {
    val targetType = T::class.java
    if(targetType.typeParameters.isEmpty()){
        return getInstance(T::class.java)
    }
    else {
        val targetTypeSpecifically = Key.get(object: TypeLiteral<T>(){})
        return getInstance(targetTypeSpecifically)
    }
}
I'm wondering what the compiler does with dead-code-elimination of the type that gets created for
targetTypeSpecifically
. For the case where the type isnt generic (we take the true branch) Will that create a new
Class
entry at runtime or wont it? Whats the best way for me to test that?
u
Compiler doesn’t eliminate anything here. The object literal will be inlined to every call site of this function, so each call will result in +1 .class file in your app, but at runtime, only objects where that branch is taken will be created
g
yeah @udalov i was hoping to avoid the plethora of class files. I wonder if i can get guice to use a synthetic lambda type here? Given that I cant get the compiler to do anything with this if statement, I suppose two methods with different names would be best here. Theres no nope of an overload either. Hmm. Guice really was designed for java.
I wonder if theres a hack like TypeLiteral I can use thats backed by a lambda instead of an old school anonymous class...
u
Maybe you can use the experimental
kotlin.reflect.typeOf
, and either deconstruct the returned
KType
as you’d like, or call
.javaType
to get a
java.lang.reflect.Type
instance representing the type
g
so @udalov im looking into this now, I think a
Type
(either kotlin or java) is definately what I want, since it seems to be purely a handle (ie a string --no class-pool involved) and it reifies generics. the Guice guys already support a java.lang type. I am having trouble getting from the
typeOf()
operator to a java.lang type. the
.javatype
property seems to throw for any argument, and i have to do the replacement of kotlin aliases myself. Very interesting stuff anyways.
u
java.lang.reflect.Type
is a bit more than a string, it actually references
java.lang.Class
objects when needed. For example, for the simplest case when a type = class, you’ll just have an instance of
Class
(which inherits from
Type
). For generic class types, you’ll get a
ParameterizedType
with arguments who are again `Type`s, and so on. Take a look at subclasses of
java.lang.reflect.Type
for more info. If you encountered a case when
typeOf<...>().javaType
throws on some type and you can reasonably minimize/isolate it, please report it to our YouTrack
g
I did but it was for kotlin 1.3.61, It also doesnt seem to do the mapping of
kotlin.collections.List<kotlin.String>
to
java.util.List<? extends java.lang.String>
like i expected it to
anyways this stuff is very interesting, thanks for your help!
I did end up with a much nicer, much-reduced-nested-class kotlin DSL for my code, and ill put together a PR for some of the kotlin-guice wrappers based on it.