I have this java code:
class ScratchBot extends TelegramLongPollingBot {
private final Action handler = new UpdateHandler();
@Override public void onUpdateReceived(Update update) {
BotApiMethod<out BotApiObject> action =
handler.createExecutableForChat(update.getMessage().getChatId());
execute(action);
}
}
interface Action {
BotApiMethod<? extends BotApiObject> createExecutableForChat(long chatId);
}
class UpdateHandler implements Action {
@Override
public BotApiMethod<? extends BotApiObject> createExecutableForChat(long chatId) {
return new SendMessage();
}
}
It works perfectly in java, but when i convert it in Kolin it breaks and this code below doesnāt work.
internal class ScratchBot : TelegramLongPollingBot() {
private val handler: Action = UpdateHandler()
override fun onUpdateReceived(update: Update) {
val action: BotApiMethod<out BotApiObject?> =
handler.createExecutableForChat(update.message.chatId)
execute(action)
}
}
internal interface Action {
fun createExecutableForChat(chatId: Long): BotApiMethod<out BotApiObject?>?
}
internal class UpdateHandler : Action {
override fun createExecutableForChat(chatId: Long): BotApiMethod<out BotApiObject?> {
return SendMessage()
}
}
Compiler throws this exception on execute call
Type mismatch.
Required:
BotApiMethod<CapturedType(out BotApiObject?)!>!
Found:
BotApiMethod<out BotApiObject?>?
I use library rubenlagus/TelegramBots: Java library to create bots using Telegram Bots API
And here is some its source code to show class hierarchy:
// Signature of execute() method that's used in my java code, be careful, Method here is a TypeVariable
public <T extends Serializable, Method extends BotApiMethod<T>> T execute(Method method) { /* */ }
// What my handler actually returns
public class SendMessage extends BotApiMethod<Message> { /* */ }
// My handler return type is java's BotApiMethod<? extends BotApiObject> or kotlin's BotApiMethod<out BotApiObject>
public abstract class BotApiMethod<T extends Serializable> extends PartialBotApiMethod<T> { /* */ }
public class Message implements BotApiObject { /* */ }
public interface BotApiObject extends Serializable { /* */ }
I also should mention that first i tried to write it in kotlin, and only after struggling for ~2 days i rewrote the ScratchBot class in java. Yeah, it also works with kotlin classes, so even if i leave Action and UpdateHandler in kotlin, i still can use them in java without any problems.