The question is about the getClass() method of the Object class and its behavior as a "static" method.
According to the Java API, the getClass() method is not static and its use is intended to access the class of the object that calls it. So far so good.
The conflict comes with the following lines of code:
// load and set background image
URL urlBackgroundImg = getClass().getResource("img/board.png");
this.imgBackground = new ImageIcon(urlBackgroundImg).getImage();
These lines are part of larger code (the purpose of which is irrelevant) and are found at the beginning of the constructor . The code is the following:
import java.awt.Image;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ChessGui extends JPanel {
private static final long serialVersionUID = 3114147670071466558L;
private static final int COLOR_WHITE = 0;
private static final int COLOR_BLACK = 1;
private static final int TYPE_ROOK = 1;
private static final int TYPE_KNIGHT = 2;
private static final int TYPE_BISHOP = 3;
private static final int TYPE_QUEEN = 4;
private static final int TYPE_KING = 5;
private static final int TYPE_PAWN = 6;
private static final int BOARD_START_X = 301;
private static final int BOARD_START_Y = 51;
private static final int TILE_OFFSET_X = 50;
private static final int TILE_OFFSET_Y = 50;
private Image imgBackground;
// 0 = bottom, size-1 = top
private List<Piece> pieces = new ArrayList<Piece>();
public ChessGui() {
// load and set background image
URL urlBackgroundImg = getClass().getResource("img/board.png");
this.imgBackground = new ImageIcon(urlBackgroundImg).getImage();
// create and place pieces
//
// rook, knight, bishop, queen, king, bishop, knight, and rook
createAndAddPiece(COLOR_WHITE, TYPE_ROOK, BOARD_START_X + TILE_OFFSET_X * 0,
BOARD_START_Y + TILE_OFFSET_Y * 7);
createAndAddPiece(COLOR_WHITE, TYPE_KNIGHT, BOARD_START_X + TILE_OFFSET_X * 1,
BOARD_START_Y + TILE_OFFSET_Y * 7);
createAndAddPiece(COLOR_WHITE, TYPE_BISHOP, BOARD_START_X + TILE_OFFSET_X * 2,
BOARD_START_Y + TILE_OFFSET_Y * 7);
createAndAddPiece(COLOR_WHITE, TYPE_KING, BOARD_START_X + TILE_OFFSET_X * 3,
BOARD_START_Y + TILE_OFFSET_Y * 7);
createAndAddPiece(COLOR_WHITE, TYPE_QUEEN, BOARD_START_X + TILE_OFFSET_X * 4,
BOARD_START_Y + TILE_OFFSET_Y * 7);
createAndAddPiece(COLOR_WHITE, TYPE_BISHOP, BOARD_START_X + TILE_OFFSET_X * 5,
BOARD_START_Y + TILE_OFFSET_Y * 7);
createAndAddPiece(COLOR_WHITE, TYPE_KNIGHT, BOARD_START_X + TILE_OFFSET_X * 6,
BOARD_START_Y + TILE_OFFSET_Y * 7);
createAndAddPiece(COLOR_WHITE, TYPE_ROOK, BOARD_START_X + TILE_OFFSET_X * 7,
BOARD_START_Y + TILE_OFFSET_Y * 7);
// pawns
for (int i = 0; i < 8; i++) {
createAndAddPiece(COLOR_WHITE, TYPE_PAWN, BOARD_START_X + TILE_OFFSET_X * i,
BOARD_START_Y + TILE_OFFSET_Y * 6);
}
createAndAddPiece(COLOR_BLACK, TYPE_ROOK, BOARD_START_X + TILE_OFFSET_X * 0,
BOARD_START_Y + TILE_OFFSET_Y * 0);
createAndAddPiece(COLOR_BLACK, TYPE_KNIGHT, BOARD_START_X + TILE_OFFSET_X * 1,
BOARD_START_Y + TILE_OFFSET_Y * 0);
createAndAddPiece(COLOR_BLACK, TYPE_BISHOP, BOARD_START_X + TILE_OFFSET_X * 2,
BOARD_START_Y + TILE_OFFSET_Y * 0);
createAndAddPiece(COLOR_BLACK, TYPE_QUEEN, BOARD_START_X + TILE_OFFSET_X * 3,
BOARD_START_Y + TILE_OFFSET_Y * 0);
createAndAddPiece(COLOR_BLACK, TYPE_KING, BOARD_START_X + TILE_OFFSET_X * 4,
BOARD_START_Y + TILE_OFFSET_Y * 0);
createAndAddPiece(COLOR_BLACK, TYPE_BISHOP, BOARD_START_X + TILE_OFFSET_X * 5,
BOARD_START_Y + TILE_OFFSET_Y * 0);
createAndAddPiece(COLOR_BLACK, TYPE_KNIGHT, BOARD_START_X + TILE_OFFSET_X * 6,
BOARD_START_Y + TILE_OFFSET_Y * 0);
createAndAddPiece(COLOR_BLACK, TYPE_ROOK, BOARD_START_X + TILE_OFFSET_X * 7,
BOARD_START_Y + TILE_OFFSET_Y * 0);
for (int i = 0; i < 8; i++) {
createAndAddPiece(COLOR_BLACK, TYPE_PAWN, BOARD_START_X + TILE_OFFSET_X * i,
BOARD_START_Y + TILE_OFFSET_Y * 1);
}
// create application frame and set visible
//
JFrame f = new JFrame();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.setResizable(false);
f.setSize(this.imgBackground.getWidth(null), this.imgBackground.getHeight(null));
}
/**
* create a game piece
*
* @param color color constant
* @param type type constant
* @param x x position of upper left corner
* @param y y position of upper left corner
*/
private void createAndAddPiece(int color, int type, int x, int y) {
Image img = this.getImageForPiece(color, type);
Piece piece = new Piece(img, x, y);
this.pieces.add(piece);
}
/**
* load image for given color and type. This method translates the color and
* type information into a filename and loads that particular file.
*
* @param color color constant
* @param type type constant
* @return image
*/
private Image getImageForPiece(int color, int type) {
String filename = "";
filename += (color == COLOR_WHITE ? "w" : "b");
switch (type) {
case TYPE_BISHOP:
filename += "b";
break;
case TYPE_KING:
filename += "k";
break;
case TYPE_KNIGHT:
filename += "n";
break;
case TYPE_PAWN:
filename += "p";
break;
case TYPE_QUEEN:
filename += "q";
break;
case TYPE_ROOK:
filename += "r";
break;
}
filename += ".png";
URL urlPieceImg = getClass().getResource("img/" + filename);
return new ImageIcon(urlPieceImg).getImage();
}
}
Note that the getClass() method does not need an object to be called, as if it were a static method.
Now, let's look at the following test code I made to play with the method:
import java.awt.Image;
import java.net.URL;
import javax.swing.ImageIcon;
public class Prueba {
public Prueba() {}
public static void main(String[] args) {
// TODO Auto-generated method stub
Prueba test1 = new Prueba();
System.out.println("TEST_1 = "+test1.getClass());
// load and set background image
Image imgBackground;
URL urlBackgroundImg = getClass().getResource("/ch01/img/board.png");
imgBackground = new ImageIcon(urlBackgroundImg).getImage();
}
}
The crucial difference from the previous one is that this time the getClass() method is called outside of a constructor to be called inside a static block. I get the error : Cannot make a static reference to the non-static method getClass() from the type Object , which is what we would expect from this method according to its definition, which confirms that it is not static.
So how is it possible that getClass() is called "statically" in the constructor and then not in the main of the test code?
And I say "statically" because a static method uses the name of the class and it doesn't even use that, but puts its name directly. As far as I've seen, you can only use the method name directly to call it if it's built into the same class that's using it. For example, a class with two methods and one of them has, within its code block, a call to the other.
Referring to this block:
You ask yourself the following:
Actually, in that context
getClass()
it is NOT called statically . It is simply called without putting the object instance in front of it because there you are calling the methodgetClass()
of the class itself, that is, ofChessGui
.When you call a method of the class itself, you do so directly. The same thing happens there with
getClass()
. To check this, you can simply put this in the constructor and you will see that what is printed isChessGui
:As for using
getClass()
from a static context, you can do so using what's known as a Class literal .O well: