学习《Design Patterns in java》的immutable object时,产生了以下疑惑:
public final class EmployeeModel {
private  final String firstName;   
private  final String lastName;
//书上是按上面方式定义的,运行正常
       //我改动成下面的样子
       //private static final String firstName;
      //private static final String lastName;
     //结果出错,显示“空白终态字段 firstName 可能尚未初始化”
    //然后我又改成下面的样子
   //private static String firstName;
  //private static  String lastName;
  //结果运行正常
public EmployeeModel(String fn,String ln)
{
firstName=fn;
lastName=ln;
}

public String getFirstName(){
return firstName;
}

public String getLastName(){
return lastName;
}
}
第一种情况我无法理解为什么运行正常,因为final不是应该“在定义的时候必须初始化”吗?
既然第一种和第三种情况都运行正常,那为什么第二种情况又出错了呢?
麻烦解释一下出现这种情况的原因

解决方案 »

  1.   

    final如果没有在定义时初始化,则一定要在构造器里面初始化,所以第一种情况正常。
    你把它声明成static后,它不能在构造器里面初始化,转而要用静态代码块才能初始化:static{
        firstName=...;
    }
      

  2.   

    都是些Java基础,把基本功打扎实点就不怕这些问题了
      

  3.   


     private static final String firstName;
          private static final String lastName;
          static{
           firstName = "";
           lastName = "";
          }这样就不会报错了,因为static是独立于对象实例的,static的final变量,要么在静态代码块里面进行初始化,要么在定义的时候进行初始化。
    而非static的final变量,要么在构造函数进行初始化,要么在实例代码块进行初始化。
    总之,final变量在为初始化之前不能使用。
      

  4.   

    第三种情况中,变量定义成static,却可以在构造函数中赋值,而且运行通过了,说明static变量是可以在构造函数中赋值的,能解释一下吗?
      

  5.   


    class A{
       static int b;
       A(int b){
    this.b=b;
       }
       void display(){
    System.out.println(b);
       }
    }public class Test{
       public static void main(String[] args){
    System.out.println(A.b);
    new A(8).display();
    System.out.println(A.b);
       }
    }结果是:
    0
    8
    8
    说明static变量可以不赋值,因为系统会自动給它赋0.然后就可以在构造函数中再改变它的值了
      

  6.   

    这个是语法要求吧 没太关深究
    个人认为 和加载时间有关:
    一个是在实例化的时候 
    一个是在类加载的时候private  final  String firstName;
    这个要在构造器中初始化private static final  String firstName;
    这个要在声名的地方初始化
     
      

  7.   

    结合楼上的回答,总结一下现在的想法:
    1,final类型变量,必须在定义的时候赋值或者在构造函数里赋值,否则报错;
    2,static类型变量,应该在定义时赋值,要是不给它赋值,int型的变量系统会自动給它赋0值
    3,static final类型变量,因为加了final,所以系统不会自动給它赋值,只能在定义时赋值或者在static块中給它赋值
    欢迎高手指点
      

  8.   

    系统不会自动給它赋值
    ==============
    这句话感觉有问题,JAVA默认就是给0,你加了static final也是一样
    但是由于加了final就必须给他赋值,否则编译错误
    又由于加了static,你可以不创建对象访问属性如A.b,所以你在构造函数中赋值相当于这个情况依然没被赋值,final就会出错
    而静态赋值的时候,你使用A.b访问依然是被赋值的
      

  9.   

    第一种情况我无法理解为什么运行正常,因为final不是应该“在定义的时候必须初始化”吗?
    java 中final定义的成员变量 并不一定必须在定义的时候初始化,final本身的含义是一旦赋值以后不可更改变量的值,final定义的变量只要在实际的类的对象在使用前得到初始化即可,例如上面例子中这两个final成员变量在构造方法中分别进行了初始化。
    既然第一种和第三种情况都运行正常,那为什么第二种情况又出错了呢?
    麻烦解释一下出现这种情况的原因static定义的成员变量跟具体的类对象无关,又加上final修饰符以后,必须在定义时就马上初始化,不知道lz明白了没,
    你可以看下这个地址,讲的蛮清楚的
    http://www.bianceng.cn/Programming/Java/200705/1523.htm这些都是java的一些基础,lz搞明白这些基础以后就不会混淆了
      

  10.   

    感谢9楼的回答。没做过项目,平常做的一些小程序都没用过final,static final,而且看的别人的代码都是在定义的时候就直接赋值了,所以也没留意还有其他的用法。刚才翻了下《thinking in java》,发现关于这个知识点的内容讲的很详细,决定再认真读读这本书。由于已经结帖了,没办法再給分了,sorry了