【问题标题】:Java call a method before constructorJava 在构造函数之前调用方法
【发布时间】:2015-08-20 18:07:05
【问题描述】:

我有一个带有方法 setMapName 的 Map 类,它从 Enum mapName 中选择来设置它,在构造函数内部有一个规则,可以根据 mapName 值从数组扇区中命名一个单元格 Alien 或 Human,我想测试单元格的名称是否确实是 Alien 或 Human,但我得到 null。

public class Map {
    private Name mapName;
    private final Sector [][] sector;
    private int Matrix [][];
    private static final int X=23;
    private static final int Y=14;
    public Map (){
        sector = new Sector[X][Y];
        for (int i=0; i < X; i++){
            for (int j=0; j<Y; j++) {
                sector[i][j] = new Sector (i,j);
            }
        }
        Matrix = new int[23][14];
        if(mapName==Name.FERMI){
            sector[10][8]=new Alien(10,8);
            sector[10][9]=new Human(10,9);
        }
        if(mapName==Name.GALILEI||mapName==Name.GALVANI){
            sector[10][5]=new Alien(10,5);
            sector[10][7]=new Human(10,7);
        }
    }
    public int[][] getMatrix() {
        return Matrix;
    }   
    public void setMatrix(int matrix[][]) {
        Matrix = matrix;
    }
    public Name getMapName() {
        return mapName;
    }
        public void setMapName(Name mapName) {//this is the method i want to use before the constructor
            this.mapName = mapName;
        }
        public Sector[][] getSectors(){
            return sector;
        }
        public void addSectors(){
            Sector.add(sector);
        }
    }

    public enum Name {
    FERMI, GALILEI, GALVANI
    }

    public class MapTest {
        @Test
        public void testMapAlien(){
            Map map = new Map();
            map.setMapName(Name.FERMI);
            assertEquals(Name.Alien, map.getSectors()[10][8].getSectorName());
        }
    }

【问题讨论】:

    标签: java methods constructor call


    【解决方案1】:

    您的 setMapName 是您的 Map 类上的非静态成员函数(因为它与 java.util.Map 冲突而命名不佳)。这意味着它可以在 Map 的现有实例上调用(例如,已经构建的 Map)。

    您的问题是您在调用构造函数后调用setMapName,但您的构造函数需要有效的Name 才能正常工作!这是一个典型的先有鸡还是先有蛋的问题。

    为什么不直接将MapName 传递给构造函数?

    public Map (Name mapName){
            sector = new Sector[X][Y];
            for (int i=0; i < X; i++){
                for (int j=0; j<Y; j++) {
                    sector[i][j] = new Sector (i,j);
                }
            }
            Matrix = new int[23][14];
            if(mapName==Name.FERMI){
                sector[10][8]=new Alien(10,8);
                sector[10][9]=new Human(10,9);
            }
            if(mapName==Name.GALILEI||mapName==Name.GALVANI){
                sector[10][5]=new Alien(10,5);
                sector[10][7]=new Human(10,7);
            }
            ...
    }
    

    【讨论】:

      【解决方案2】:

      您的问题是您没有初始地图名称。当您调用构造函数时,mapName 为空。所以...

      您可以通过两种方式做到这一点:

      //Constructor with argument mapName
      public Map (Name mapName){
       setMapName(mapName); //or this.mapName = mapName;
       ...
      }
      

      或者:

      //Give a value to mapName on the constructor without arguments, but I recommend the first one to your case.
      public Map (){
       ...
       mapName = value;
       ...
       setMapName(mapName);
      }
      

      【讨论】:

      • 为什么你会在设置成员变量后立即setMapName(mapName)(例如mapName = value)?
      • 这是一个例子,表明他必须先初始化变量。
      猜你喜欢
      • 2021-08-21
      • 1970-01-01
      • 1970-01-01
      • 2012-09-28
      • 1970-01-01
      • 1970-01-01
      • 2011-03-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多