简体   繁体   English

需要在Java中的参数化构造函数中初始化最终引用

[英]Need for initializing final reference within parameterized constructor(s) in Java

import java.util.*;

public Class C
{
     final Vector v;
     C()
     {
          v=new Vector();
     }

     C(int i)
     {
          //Here, it is an error. v might not have been initialized.
     }

     public void someMethod()
     {
           System.out.println(v.isEmpty());
     }

     public static void main(String[] args)
     {
          C c=new C();
          c.someMethod();
     }
} 

The Above code is a compile time error. 上面的代码是编译时错误。 I know but it says( in NetBeans) variable v should be initialized. 我知道,但是它说(在NetBeans中)变量v应该被初始化。 When I initialized it in the overloaded constructor it fixes the problem and prints "true". 当我在重载的构造函数中对其进行初始化时,它可以解决问题并显示“ true”。 My problem is why should I initialize it again in the overloaded version of constructors.(I have initialized it once in the default constructor ) and I'm not even using the overloaded version. 我的问题是为什么我应该在构造函数的重载版本中再次对其进行初始化(我已经在默认构造函数中对其进行了一次初始化),而且我什至没有使用重载版本。 Why? 为什么?

Because the overloaded constructor does not invoke the default one. 因为重载的构造函数不会调用默认的构造函数。

Use this() to invoke it. 使用this()调用它。

When you create a new object, only one of the constructors of your class is called to initialize the object. 创建新对象时,仅调用类的构造函数之一来初始化对象。 You seem to think that all of the constructors are called, or that the default (no-arguments) constructor is always called. 您似乎认为所有构造函数都已调用,或者总是调用默认(无参数)构造函数。 That is not the case. 事实并非如此。

So, each constructor needs to initialize all the final member variables. 因此,每个构造函数都需要初始化所有final成员变量。

Note that from one constructor you can explicitly call another one using this(...) . 请注意,您可以使用this(...)从一个构造函数显式调用另一个构造函数。 For example, as the first line of your C(int i) constructor, you could add a line: this(); 例如,作为C(int i)构造函数的第一行,您可以添加一行: this(); to call the C() constructor. 调用C()构造函数。 Another solution is to initialize the member variable at the line where you declare it: 另一个解决方案是在声明它的行上初始化成员变量:

public class C {
    // v will be initialized, no matter which constructor will be used
    final Vector v = new Vector();

    C() {
    }

    C(int i) {
        // ...
    }

    // ... etc.
}

Note that you don't need to explicitly initialize non- final member variables; 注意,您不需要显式初始化非final成员变量; if you don't initialize those, Java will initialize them with a default value (which is null for non-primitive type variables). 如果不初始化它们,则Java将使用默认值(对于非原始类型变量为null初始化它们。 However, you do need to explicitly initialize final member variables. 但是,您确实需要显式初始化final成员变量。

Another note: Vector is a legacy collection class. 另一个注意事项: Vector是旧式收集类。 You should prefer using ArrayList instead. 您应该更喜欢使用ArrayList

Third note: Use generics to make your code more type-safe. 第三注:使用泛型使代码更加类型安全。 For example, if you need to store strings in a list, use ArrayList<String> instead of the raw type ArrayList . 例如,如果您需要将字符串存储在列表中,请使用ArrayList<String>而不是原始类型ArrayList

Overloaded constructor does not call the other version unless you explicitly do it with 除非您明确使用重载的构造函数,否则它不会调用其他版本

this();

That's probably what you want to do. 那可能就是你想做的。

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

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