创建对象时是否可以初始化最终变量?

时间:2013-09-03 05:25:00

标签: java final

如何才能在对象的创建时初始化类的最终变量?

任何人都可以解释它是怎么可能的? ...

8 个答案:

答案 0 :(得分:21)

您必须只初始化一次最终变量一次。实例变量有三种方法:

  1. 在构造函数中
  2. 在实例初始化块中。
  3. 宣布时
  4. 以下是这三个例子:

    public class X
    {
        private final int a;
        private final int b;
        private final int c = 10;
    
        {
           b = 20;
        }
    
        public X(final int val)
        {
            a = val;
        }
    }
    

    在每种情况下,当您调用new X(...)并且无法再次调用任何代码时,代码会运行一次,这样就可以满足初始化的要求,每次实例只执行一次。

答案 1 :(得分:6)

在声明期间未初始化的最终变量称为空白最终变量,必须初始化on all constructor either explicitly or by calling this()。如果没有这样做,编译器会抱怨"final variable (name) might not be initialized".


根据维基百科

最终变量只能通过初始值设定项或赋值语句初始化一次。它不需要在声明点初始化:这称为"blank final"变量。必须在声明它的类的每个构造函数的末尾明确赋值类的空白最终实例变量;类似地,必须在声明它的类的静态初始值设定项中明确赋值空白的最终静态变量;否则,在两种情况下都会发生编译时错误。

例如

public class Sphere {

    // pi is a universal constant, about as constant as anything can be.
    public static final double PI = 3.141592653589793;  

    public final double radius;
    public final double xPos;
    public final double yPos;
    public final double zPos;

    Sphere(double x, double y, double z, double r) {
         radius = r;
         xPos = x;
         yPos = y;
         zPos = z;
    }

    [...]
}

有关详细信息,请阅读Wiki页面 http://en.wikipedia.org/wiki/Final_(Java)

答案 2 :(得分:0)

为什么不呢。喜欢这个

public class GenericFoo{

    final int var;

    GenericFoo(){
        var = 100;
    }

}

答案 3 :(得分:0)

您可以在构造函数完成之前初始化最终实例变量 根据{{​​3}}

  

必须在声明它的类的每个构造函数的末尾明确赋值空白的最终实例变量;否则会发生编译时错误。

Java中的空白最终变量是一个最终变量,在声明时未初始化

所以有两种方法可以做到。

方式1:在构造函数

class Program {
    final int i3;   
    Program() {
        i3 = 10;
    }
}

方式2:在实例块中

class Program {
       final int i3;   
       {
             i3 = 10;
        }
    }

答案 4 :(得分:0)

final值只能设置一次,并且只能在构造函数中设置。构造函数无法将其设置为您喜欢的任何值。

如果你有一个你希望成为所有实例的常量的值,你可以使它static final,你将无法在构造函数中设置它。也许你会让两者混淆。

答案 5 :(得分:0)

如果您指的是静态最终成员,则可以使用静态初始化程序:

class Example {
  public final static Map<String,Object> C;

  static {
    C = new HashMap<>();
    C.put("hi", 5);
  }
}

答案 6 :(得分:0)

由于JVM在内部的工作方式以及Java的设计方式,这是可能的。

编译代码后,生成的.class文件将包含代码的字节码表示。类文件只不过是按照定义的顺序构造的一堆字节,可以由JVM解释。

在类文件结构中,您将能够找到称为常量池的内容,它只是加载类时JVM使用的符号引用表。您的最终变量将在此处找到,无论它们是否已初始化为文字。

现在您已经知道了,让我们继续思考最终修饰符的含义,它只是告诉JVM在这种情况下将为变量赋值的一种方式,一旦完成,不允许对该变量进行重新赋值操作,因此,如Java语言文档所述,最终变量可以只赋值一次。

现在您已具备此背景,以便直接回答您的问题:

无论您的变量是对象还是基本类型,JVM都会使用运行时常量池中的值为对象自动设置不是类成员(意味着不是静态)的最终变量的值或者,如果此变量未在声明中初始化,则在构造函数运行时将需要设置它。所有这一切都是可能的,因为Java的设计方式是为程序员提供变量赋值的一些灵活性,以避免硬编码,并提供一种将对象分配给最终引用的方法。

就像最后一个提示一样,不要将最终变量视为C ++中的常量。它们可能看似相似,但它们不是,它们的处理方式完全不同。

答案 7 :(得分:0)

如你所知,实例变量只与类对象相关联,而变量之前的最终关键字意味着你不能改变变量的值,所以变量存在只有在创建了对象时我们才能分配最终变量值在创建对象之前如上所述的三种方式(例如,通过静态块,当你声明时)或在创建对象时(例如通过构造函数)