1

I have recently started using generic methods in my projects. I am working on a chess project where every piece class extends to Pieces.java.

Diagram of my pieces package

And in the Player.java, I have added this code:

public class Player {
    Pieces[] pieces = new Pieces[16];
    Player() {
        …
        init();
    }
    private void init() {
        //initialize pieces array with all pieces.
        pieces[0] = new Pawn(new Point(6, 0), this);
        pieces[1] = new Pawn(new Point(6, 1), this);
        pieces[2] = new Pawn(new Point(6, 2), this);
        pieces[3] = new Pawn(new Point(6, 3), this);
        pieces[4] = new Pawn(new Point(6, 4), this);
        pieces[5] = new Pawn(new Point(6, 5), this);
        pieces[6] = new Pawn(new Point(6, 6), this);
        pieces[7] = new Pawn(new Point(6, 7), this);
        pieces[8] = new Rook(new Point(7, 0), this);
        pieces[9] = new Knight(new Point(7, 1), this);
        pieces[10] = new Bishop(new Point(7, 2), this);
        pieces[11] = new Queen(new Point(7, 3), this);
        pieces[12] = new King(new Point(7, 4), this);
        pieces[13] = new Bishop(new Point(7, 5), this);
        pieces[14] = new Knight(new Point(7, 6), this);
        pieces[15] = new Rook(new Point(7, 7), this);
    }
    public <T extends Pieces> T getPiece(Point point) {
        for(Pieces piece: pieces) {
            if(piece.isAlive() && piece.getCurrentPoint().equals(point))
                return (T)piece;
        }
        return null;
   }
}

But now, IntelliJ gives me a warning, "Unchecked cast from "Pieces" to T. Even when I mentioned that and all the elements of pieces array is a subclass of Pieces, even then IntelliJ gives me a warning: "Unchecked cast from Pieces to T". How am I supposed to fix this.

Please do not mark this as duplicate because the answer of other questions have not helped me.

walen
  • 7,103
  • 2
  • 37
  • 58
Nishant Jalan
  • 844
  • 9
  • 20
  • 3
    Why isn't your `getPiece` defined simply as `public Pieces getPiece(Point point)`? – RealSkeptic Apr 15 '19 at 13:10
  • Why are you casting it? – Murat Karagöz Apr 15 '19 at 13:11
  • 2
    You can invoke this method with `Pawn p = getPiece(point);` and `Queen q = getPiece(point);` (where `point` is intentionally the same in both invocations). Only one of these can succeed (unless it returns `null`, of course). – Andy Turner Apr 15 '19 at 13:11
  • I do not think you need generics here. Polymorphism should take care of your situation. – PM 77-1 Apr 15 '19 at 13:12
  • Of course I can define it as public Pieces getPiece(Point point). But I want to have a practice using generic methods. I cant understand what's wrong here. That's why I have asked this question. – Nishant Jalan Apr 15 '19 at 13:13
  • What is wrong is that you say that this function is going to return a particular subtype of `Pieces`, to be determined by the compile-time context of the call, and you cast to that particular subtype without knowing in advance that the piece you are returning is, indeed, of that subtype. – RealSkeptic Apr 15 '19 at 13:14
  • It's important to understand what an unchecked cast means: it means that there is no `checkcast` instruction inserted there by the compiler. However, a cast is inserted at the call site: `Pawn p = getPiece(point);` is actually compiled to `Pawn p = (Pawn) getPiece(point);`. So there is a checked cast *there*, and this might fail at runtime. It is better just to return a `Pieces` (rename that to `Piece`, btw), and force the caller to cast explicitly, so they can see the potential failure explicitly. – Andy Turner Apr 15 '19 at 13:19

0 Answers0