can anyone help with my question on <KT-54309>?
# compiler
a
can anyone help with my question on KT-54309?
d
Answered
a
Thanks! I do get an error when trying to invoke the method itself:
d
Exactly, there is an error because it is unsafe Consider the following example (which is more or less identical to yours)
Copy code
class Box<T>(var x: T)

fun test(b: Box<*>) {
    val a: Any? = b.x
    b.x = "hello" // unsafe, error
}

fun main() {
    val box = Box(1)
    test(box)
}
Inside function
test
you don't know which exact
Box
was passed inside So the type of
b
is actually
Box<Captured(*)>
Captured(*)
means that it is some type which can be passed outside. It may be
Int
, it may be
String
, it maybe anything. So when you try to read
b.x
it will return this
Captured(*)
, which getting approximated to
Any?
(as there are no bounds which reduces the set of possible types for it) But if
Captured(*)
stands in input position (like in setter method or when you just assign something to property of such type), there is actually no any reasonable type for it You can't assign
String
to
b.x
, as at call site you can pass
Box<Int>
You can't assign
Int
to
b.x
, as at call site you can pass
Box<String>
a
Hmm. So is there any way to invoke this method from kotlin? or is it not possible?
in 2.0.0
d
And KT-54309 stands for the same situation form my example above, but when
Box
is not kotlin class but java class with getter and setter instead of property There was a bug which allowed to write something to such synthetic property, which may lead to runtime exceptions:
Copy code
public class Box<T> {
    public Box(T x) {this.x = x;}

    private T x;

    public T getX() {return x;}

    public void setX(T x) {this.x = x;}
}
Copy code
fun test(b: Box<*>) {
    b.x = 10
}

// compiles with K1
fun main() {
    val box = Box("hello")
    test(box)
    box.x.length // ClassCastException
}
You can call this method with unchecked cast, but only if you are really sure that it is safe and you won't get an exception at runtime (compiler warned you)
Copy code
fun test(b: Box<*>) {
    @Suppress("UNCHECKED_CAST")
    (b as Box<Int>).setX(10)
}
a
still not working for me 😞 is there a warning that I can suppress for the fact that kotlin expects the value to be Nothing?
d
You need to cast to some specific type which allows you to set the value you want Check my last example again: I'm casting
Box<*>
to
Box<Int>
to get an ability to write
Int
to
x
a
ok let me try that
(producerFactory as DefaultKafkaProducerFactory<String ,Any>)
worked!
thanks!!!
d
You are welcome
a
This is a little over my head so i appreciate your help