1
訪問者パターンbutのようなものを戻り値とともに使用しようとしています。汎用戻り型の訪問者パターンのJava/Kotlinキャスト例外
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.CharSequence;
at Printer.combine(...)
at Split.accept(...)
at MWEKt.main(...)
コード:明示的なキャストが存在しないものの
しかし、私はClassCastExceptionが取得しています
interface TreeElem {
fun <T> accept(visitor: TreeVisitor<T>): T
}
class Leaf: TreeElem {
override fun <T> accept(visitor: TreeVisitor<T>): T {
return visitor.visit(this)
}
}
class Split(val left: TreeElem, val right: TreeElem): TreeElem {
override fun <T> accept(visitor: TreeVisitor<T>): T {
return visitor.combine( // this causes cast error
visitor.visit(this),
left.accept(visitor),
right.accept(visitor))
}
}
interface TreeVisitor<T> {
// multiple implementations with different T in future (only one in this example)
fun visit(tree: Leaf): T
fun visit(tree: Split): T
fun combine(vararg inputs: T): T
}
class Printer: TreeVisitor<CharSequence> {
override fun combine(vararg inputs: CharSequence): CharSequence { // error here
return inputs.joinToString(" ")
}
override fun visit(tree: Leaf): CharSequence { return "leaf" }
override fun visit(tree: Split): CharSequence { return "split" }
}
fun main(args: Array<String>) {
val tree = Split(Leaf(), Leaf())
val printer = Printer()
println(tree.accept(printer))
}
を、私は、問題が何であるかを知りません。私は何か不可能なことをしようとしているのですか、それとも正しく表現していないのですか?
私の考え、これまで:
Printer.combine
がCharSequence
の期待します。- 私は
CharSequence
- コンパイラはおそらくJVMコード(型消去?)
- にキャストを挿入しかし、ランタイム型に互換性があるので、キャストは を動作するはずが返さ
TreeElem.accept
の一般的な過負荷を呼んでいます
最後の点は現実主義者と衝突しているので、間違って何かを理解している可能性があります。
編集:私はそれがKotlinの問題だかどうかを確認するために、答えを誘致するためにJavaにMWEを翻訳しました:
interface TreeElem {
<T> T accept(TreeVisitor<T> visitor);
}
class Leaf implements TreeElem {
public <T> T accept(TreeVisitor<T> visitor) {
return visitor.visit(this);
}
}
class Split implements TreeElem {
private TreeElem left;
private TreeElem right;
Split(TreeElem left, TreeElem right) {
this.left = left;
this.right = right;
}
public <T> T accept(TreeVisitor<T> visitor) {
return visitor.combine(
visitor.visit(this),
left.accept(visitor),
right.accept(visitor));
}
}
interface TreeVisitor<T> {
T visit(Leaf tree);
T visit(Split tree);
T combine(T... inputs);
}
class Printer implements TreeVisitor<CharSequence> {
public CharSequence combine(CharSequence... inputs) {
StringBuilder text = new StringBuilder();
for (CharSequence input : inputs) {
text.append(input);
}
return text;
}
public CharSequence visit(Leaf tree) { return "leaf"; }
public CharSequence visit(Split tree) { return "split"; }
}
public class MWEjava {
public static void main(String[] args) {
TreeElem tree = new Split(new Leaf(), new Leaf());
Printer printer = new Printer();
System.out.println(tree.accept(printer));
}
}
エラーがJavaの場合も同じです。
これは意味があります、ありがとう!どういうわけか、私は '' L 'を認識しませんでした。それは配列なのでキャストが失敗したかもしれません... – Mark
それは逃すのは簡単ですが、私にはいつも起こります:) – zsmb13