0

したがって、一般的な隣接リストをコーディングしていて、コードにコンパイル エラーはありませんが、テストを実行すると、全体的に同じランタイム エラーが発生します。

java.lang.ClassCastException: [[Ljava.lang.Object; cannot be cast to [[Lds.Graph.Edge;
    at ds.TheAdjacencyMatrix.AdjacencyMatrix.<init>(AdjacencyMatrix.java:86)
    at ds.TheAdjacencyMatrix.AdjacencyMatrix.<init>(AdjacencyMatrix.java:63)
    at ds.TheAdjacencyMatrix.AdjacencyMatrix.<init>(AdjacencyMatrix.java:73)
    at ds.Graph.Test.TheAdjacencyMatrixTest.testAddVertex(TheAdjacencyMatrixTest.java:33)

エラーは、2d オブジェクト配列を E[][] 型にキャストする行のコンストラクターにあります

隣接行列に関連するコードは次のとおりです::

public class AdjacencyMatrix<T, E extends Edge> 
        implements AdjacencyMatrixInterface<T, E>, Graph<T, E> {

    //~Constants----------------------------------------------
    private static final int DEFAULT_SIZE = 10;

    //~Data Fields--------------------------------------------
    /**
     * Int matrix that holds edge weights in weighted graphs. 
     * A 1 in a directed graph indicates an edge, a 0 indicates no edge.
     */
    private E[][] matrix;

    /**
     * Array of elements contained in the graph.
     * Elements correspond to the same indices as they do in the adjacency matrix of edges.
     * 
     * i.e. matrix[4][5] is an edge from 4 to 5, 
     *  elements[4] is the element at 4, elements[5] is the element at 5
     */
    private T[] elements;

    /**
     * The maximum number of vertices in the adjacency matrix.
     */
    private int size;

    /**
     * The current number of vertices in the graph.
     */
    private int numVertices;

    /**
     * Indicates whether the graph is directed or not. True if directed, false otherwise.
     */
    private boolean directed;

    //~Constructors--------------------------------------------
    /**
     * Initializes the adjacency matrix to a size of 10.
     * Which means there are 10 vertices in the graph.
     */
    public AdjacencyMatrix() {

        this(DEFAULT_SIZE);
    }

    /**
     * Initializes the adjacency matrix to a size of 10. There will be 10 vertices in the graph.
     * 
     * @param directed true if the graph is to be a directed graph, false otherwise.
     */
    public AdjacencyMatrix(boolean directed) {

        this();
        this.directed = directed;
    }

    /**
     * Initializes the adjacency matrix to a size of size.
     * There will be a maximum size of *size* vertices in the graph
     * 
     * @param size the size of the adjacency matrix.
     */
    @SuppressWarnings("unchecked")
    public AdjacencyMatrix(int size) {

        matrix = (E[][]) new Object[size][size];
        elements = (T[]) new Object[size];

        this.size = size;
        numVertices = 0;
        directed = false;
    }

Edge クラスは抽象クラスで、そのコードは次のとおりです。

package ds.Graph;

/**
 * An abstract Edge class which has methods
 * getWeight()
 * and
 * setWeight(int weight).
 * Used for a Graph data structure to abstract
 * out the edges.
 * 
 *
 *
 */
public abstract class Edge implements Comparable<Edge> {

    /**
     * Sets the weight of the edge to the passed in weight.
     * 
     * @param weight the weight of the edge.
     */
    public abstract void setWeight(int weight);

    /**
     * Gets the weight of the edge.
     * 
     * @return the edge weight.
     */
    public abstract int getWeight();
}

編集::

したがって、これは実行時にエラーを設定するコード行です。IntEdge は、整数を保持する Edge から継承した単なるオブジェクトです。

AdjacencyMatrixInterface<String, IntEdge> matrix = new AdjacencyMatrix<String, IntEdge>(false);
4

5 に答える 5

2

その行を単純に変更します

matrix = (E[][]) new Edge[size][size];

Eクラス内の上限まで消去されます。Eの上限はEdgeこの場合です。したがって、にキャストしようとしEdge[][]ます。

また、 と がそれぞれととして外部に公開されていないことを確認する必要がmatrixあります。これらは実際にはこれらのタイプではないためです。ただし、クラス内でのみ使用する限り、問題はありません。elementsE[][]T[]

于 2013-05-20T09:12:32.413 に答える
1

問題は、Object[][] が Edge[][] のインスタンスではないことです。そのようにオブジェクトをキャストすることはできません。

new Object[][] {} instanceof Edge[][] // => false

その逆の Object[][] は、実際には Edge[][] のスーパークラスです。

new Edge[][] {} instanceof Object[][] // => true

また、 Java言語仕様によると

配列型の直接のスーパークラスは Object です。すべての配列型は、インターフェース Cloneable および java.io.Serializable を実装します。

編集:

また、Rahul Bobhate が指摘したように、ジェネリックを利用するように設計されているため、Java Collections Frameworkを使用することをお勧めします。すべての配列ベースの回避策はかなり醜いです。

于 2013-05-20T06:24:35.333 に答える
0

これは正しくありません。チェックされていないキャスト警告が表示されている必要があります。

matrix = (E[][]) new Object[size][size];
        elements = (T[]) new Object[size];

一般的な情報は実行時に消去されるため、配列インスタンスを明示的に渡す必要があります (つまり、実行中の実行中のコードは になりますmatrix = new Object[][]) 。

次のようなコンストラクターを使用できます。

public class AdjacencyMatrix<T, E extends Edge> 
        implements AdjacencyMatrixInterface<T, E>, Graph<T, E> {
E[][] matrix;
T[] elements;
public AdjacencyMatrix(int size, E[][] matrix, T[] elements) {
        this.matrix = matrix;
        this.elements = elements;
   }
}
于 2013-05-20T06:25:37.187 に答える
-1

その理由は、E は Object のサブクラスですが、E[] は Object[] のサブクラスではないためです。配列はフラットなクラス階層を持つため、互いにキャストすることはできません。

[編集]

私は間違っていました(コメントのthx)。実際、配列には型階層があります ( http://etutorials.org/cert/java+certification/Chapter+6.+Object-directional+Programming/6.5+Completing+the+Type+Hierarchy/を参照)。正しく指摘されているように、スーパータイプのインスタンスをサブタイプにキャストしようとしていますが、これは他の Java オブジェクトでは機能しません。

于 2013-05-20T08:17:51.813 に答える