简体   繁体   English

在Java中初始化变量的不同方法

[英]Different ways to initialize variables in Java

I came across the code of guessgame . 我遇到了guessgame的代码。 There is a code snippet where three player objects are initialized the following way: 有一个代码片段,其中三个播放器对象按以下方式初始化:

public class guessgame{
    Player p1;
    Player p2;
    Player p3;
    public void startGame() {
        p1 = new Player();
        p2 = new Player();
        p3 = new Player();
    ...
    }
    ...
}

The same worked when I declared and initiated it the following way as well. 当我宣布并以下列方式发起时,同样有效。

public class GuessGame {
    Player p1 = new Player();
    Player p2 = new Player();
    Player p3 = new Player();
    public void startGame(){
        ...
    }
    ...
}

Is there a difference between the two? 这两者有区别吗? In the first example, why was the three instance variables declared outside the startgame() method, and does it really matter internally? 在第一个例子中,为什么在startgame()方法之外声明了三个实例变量,它在内部真的很重要吗?

Is there a difference between the two? 这两者有区别吗?

Yes. 是。 The code in the first snippet will execute only in the context of startGame . 第一个代码段中的代码只能在startGame的上下文中startGame If you do not call startGame , the objects would remain null . 如果不调用startGame ,则对象将保持为null Every time you call startGame , the old objects, if any, would be discarded, and replaced with new ones. 每次调用startGame ,旧对象(如果有)都将被丢弃,并替换为新对象。

The second snippet would execute once for each GuessGame object when you call any of its constructors. 当您调用其任何构造函数时,第二个代码段将为每个GuessGame对象执行一次。 The code would be shared among all constructors. 代码将在所有构造函数之间共享。

In the first example, why was the 3 instance variables declared outside the startGame() method 在第一个示例中,为什么在startGame()方法之外声明了3个实例变量

The only way to declare an instance variable is to do it outside a method. 声明实例变量的唯一方法是方法之外执行。 Variables declared inside a method are locals . 在方法内声明的变量是本地变量。

Another difference between the first and the second way is that calling instance methods that access players becomes "legal" only after calling startGame in the first code snippet. 第一种方法和第二种方式之间的另一个区别是,只有在第一个代码片段中调用startGame之后,调用访问玩家的实例方法才变得“合法”。

If you initialize outside the method, then it is executed when the class is instantiated and memory is allocated for them. 如果在方法外部初始化,则在实例化类并为其分配内存时执行它。 If you don't, it just gets a null (or default value for primitives) assigned to them. 如果不这样做,它只会获得分配给它们的null(或基元的默认值)。

If you never call startgame(), then you're delaying allocating it, and perhaps the user never wants to start the game. 如果你从不调用startgame(),那么你就是在推迟分配它,也许用户永远不想开始游戏。 This is smart if the players take a lot of memory to build, and you don't want the user to wait for that to happen (memory allocation), and just run methods immediately (that don't use them). 如果玩家需要大量内存来构建,并且您不希望用户等待它发生(内存分配),并且只是立即运行方法(不使用它们),这是很聪明的。

If for some reason you have several methods that need to use the p1, p2, p3 variables, then coordination of who will initialize may be confusing, so you just might bite the bullet and initialize them upfront. 如果由于某种原因你有几个方法需要使用p1,p2,p3变量,那么初始化谁的协调可能会令人困惑,所以你可能会咬紧牙关并预先初始化它们。 If you know there will be 3 players, why bother the methods with it? 如果你知道会有3名玩家,为什么还要用它来打扰这些方法呢? Otherwise you'll have to do something like: 否则你将不得不做以下事情:

if (p1 == null){
    p1 = new Player();
}

In the second method, you simply do both things at the same time - declare and initialize. 在第二种方法中,您只需同时执行两项操作 - 声明和初始化。 The difference is, that you need to run startGame() method in the first example to initialize them. 不同之处在于,您需要在第一个示例中运行startGame()方法来初始化它们。

On your first example, the objects are instantiated only when you call the method startGame() . 在第一个示例中,只有在调用方法startGame()时才会实例化对象。 Before the call to this method, p1 , p2 and p3 are equal to null . 在调用此方法之前, p1p2p3等于null

On your second example, you declare and instantiate them directly. 在第二个示例中,您直接声明并实例化它们。 So they are instantiated at the creation of the class. 所以他们在创建类时被实例化。

1st : Initialization at method startGame() 1st:方法startGame()初始化

guessgame gg = new guessgame() // Here p1 is null

2nd : at class level 第二名:在班级

GuessGame GG = new GuessGame() // OK p1 is initialized

p1 , p2 , p3 are not local variables, but class fields. p1p2p3不是局部变量,而是类字段。

They are available to all class methods after the class instance was constructed. 构造类实例后,它们可用于所有类方法。

In the first snippet, the values of the three fields are null until the method startGame() is invoked. 在第一个代码段中,三个字段的null 直到调用方法startGame()

In the second snippet, the fields are initialized during instance construction. 在第二个片段中,在实例构建期间初始化字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM