Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

オーバーロードがうまく効かない

ArrayListを拡張したクラスの中で
public int indexOf(Class<TokenKind.Kind> kind)
というメソッドを作ったのですが、
public int indexOf(Object object)
の方が呼び出されてしまいます。
これは別名で作るしかないのでしょうか?
そもそもObjectを引数に取る方はいらないのですが。

7

回答

1521

閲覧

7件の回答

評価

0

どんなコードを書いてるのか分からんのに、的確な答えが
出せるわけなかろう。

>そもそもObjectを引数に取る方はいらないのですが。
要らないなら、そのクラスをベースにすることが間違い
だ。

評価

0

自作のTokenクラスを管理するリストを作りたいと思っています。
Tokenクラスのフィールドの1つにKindがあります。
KindとはTokenの種類を定義したenumに共通でついている
インターフェースです。

始まりはArrayList<Token>だったのですが、
特定のKindを持ったTokenの位置を知りたいと思い
ArrayListを拡張したTokenListクラスを作成し、
その中にpublic int indexOf(Kind kind)を作りました。

現在TokenListの中にあるTokenの中で特定のenumに定義されている
Kindを持つTokenの位置を調べるために
public int indexOf(Class<? extends TokenKind.Kind> kind)を
作りました。 (質問の引数は間違ってました。)

ただ呼び出すときに(Class<? extends TokenKind.Kind> kind)と
(Object object)が区別できないようで、
前者のやつを後者のやつが呼ばれてしまいます。

いっそのこと(動的もしくは静的)配列をフィールドに持つ
クラスを作成する方がこの場合いいんですかね?

//TokenKindクラスの中身
import java.util.ArrayList;

public class TokenList extends ArrayList<Token> {
    public int indexOf(TokenKind.Kind kind) {
        for (int n = 0; n < size(); n++) {
            if (get(n).kind == kind) {
                return n;
            }
        }
        return -1;
    }

    public int indexOfTokenKind(Class<? extends 
TokenKind.Kind> kind) {
        for (int n = 0; n < size(); n++) {
            if (get(n).kind.getClass() == kind) {
                return n;
            }
        }
        return -1;
    }

    public String listUp() {
        String list = "--------------------\nTokenList : " + size() 
+ "Token(s)\n";
        for (int n = 0; n < size(); n++) {
            list += get(n) + "\n";
        }
        list+="--------------------\n";
        return list;
    }
}

評価

0

なんで呼び出し側を書かないんだ…。
別のメソッドが呼ばれるなら、呼び出し側の書き方が期待
するメソッドのI/Fに合致してないからだろう。

評価

0

今回に限らず、見てもらいたいなら以下のことを考えてコ
ードを掲載すること。
・問題が再現する最低限のコード
・そのまま実行して動く

評価

0

何となく…もしや、「合致して0以上が返るはずなの
に、-1が返る。きっと引数Objectのものが呼ばれている
に違いない」と考えてないか?

そのメソッドが呼ばれているかどうかは、ステップ実行
するなり、System.out.println()を挟んでみるなりすれ
ば分かることだ。
「後者のやつが呼ばれてしま」うのではなく、判定が間
違ってるだけではないかと感じた。

今回の場合、forループ開始直後に

System.out.println(get(n).kind.getClass());

とでも挟めば分かるんじゃないか。


あと、Stringの連結方法や、拡張forといったあたり
を、先に勉強するほうがいいかもしれないな。
ここまま続けると、結果は正しくても、コードとして問
題がある(効率、パフォーマンスが悪い)ものを生産し
ていくことになるかもしれない。

評価

0

int funcPosition = tokenList.indexOf(TokenKind.Calc1.class);
のようにして呼び出しています。

(Class<? extends TokenKind.Kind> kind)と
(Object object)の違いだけでどうにかなると思っていた
私が間違ってました。
とりあえず前者のメソッド名を別のものに変えるとこの方法で呼び出せることを確認
しています。
コードを提示するためにもIdeoneでやってみたらうまくいきました。
http://ideone.com/aYcQp1

Eclipseで見てObjectの方が呼ばれているようで「?」と思っていましたが、
そのときは(Class<TokenKind.Kind> kind)と書いてしまっていたのが原因
だったのかもしれません。

あと、名前変えてうまくいっていたときにrenameで名前を変えようとしたら
「Hierarchy declares a method 'indexOf' with the same number of parameters, 
but different parameter type names.」
と言われたので、やはり変えなくてはならないのかと思っていました。
気にせず変更したらうまくいきました。

評価

0

>やはり変えなくてはならないのかと思っていました。
操作自体だめならキャンセルボタンは出ない。
OK・キャンセルは確認を促す場合のセットであり、操作の結
果に懸念があるから確認する。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。