final String 成员变量还能通过构造器赋值?

hetongfei 2018-09-09 12:45:30
按照道理来说String是不可以变的,final也是引用不变的,而类变量会先在构造器之前因为类初始化而初始化。那么它的值已经是定下来了啊。但是我在think in java一书里面看到一段代码是这样的。
class Person{
public final String first;....


public Person(String first,String last,String address){
this.first = first;....
}
}
这些是怎么回事呢?
...全文
1114 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
SunsetFeng 2018-09-15
  • 打赏
  • 举报
回复
对于final修饰的非static变量,必须保证在new对象的时候能够得到初始化,对于final修饰的static变量,要么在创建的时候赋值,要么在static区赋值
hetongfei 2018-09-13
  • 打赏
  • 举报
回复
这个是属于java设计者预留的一点小机制吗?
qq_39936465 2018-09-13
  • 打赏
  • 举报
回复
构造时用不用fianl变量有一点区别。 class Person{ public final String first; String last,address; public Person() {} /当定义时有final变量是 构造不能为空,这句会报错。 public Person(String first, String last, String address) { this.first = first; this.last = last; this.address = address; } } class Person{ public String first; String last,address; public Person() {} /没有final变量,可以定义空构造 public Person(String first, String last, String address) { this.first = first; this.last = last; this.address = address; } }
qq_39936465 2018-09-13
  • 打赏
  • 举报
回复
final可以在定义时赋初值或在定义后的其他地方赋初值,但是只能赋值一次,再次赋值会报错,就是这样,源程序定义时没有赋值,所以可以进行一次赋初值。
TJkaklf 2018-09-12
  • 打赏
  • 举报
回复
不在构造器进行赋值
2018-09-12
  • 打赏
  • 举报
回复
,而类变量会先在构造器之前因为类初始化而初始化。那么它的值已经是定下来了啊。
对于不是final 的类变量来说,它们都会在类初始化前被赋一个值。但final类变量却好像不太相同,系统认为这个东西必须让你自己进行赋值,而不能只是使用其默认值(但凡定义一个保持不变的常量,其肯定要具有一定的意义)。
elysianwu 2018-09-11
  • 打赏
  • 举报
回复
楼上正解




我的签名
irez 2018-09-11
  • 打赏
  • 举报
回复
设置String的时候只是一个常量还没赋值,也没初始化,在后构造方法中赋值并设值
liulilittle 2018-09-11
  • 打赏
  • 举报
回复
java 中 final 与 C# readonly 的作用是类似的,它只起到一个修饰限定只读的作用 -------------------------------------------ne 对于:final 友元定义只允许在实例构造器内初始化,在全局段初始化的代码,编译器自动移动代码 To 实例构造器内用户代码之前 静态定义与友元定义相同,但只允许“静态构造( [Java 称静态代码块])”
flybirding10011 2018-09-11
  • 打赏
  • 举报
回复
看看时间是否正常
flybirding10011 2018-09-11
  • 打赏
  • 举报
回复
看看时间是否正常
nayi_224 2018-09-11
  • 打赏
  • 举报
回复
个人理解。1.final修饰的变量在使用的时候必须确保初始化。2.变量在初始化后不可更改。
那么上面的问题就好解释了。
非静态的成员变量在使用前一定会先实例化类,那么只需要在构造方法或者块结束之前确保实例化即可。
咸鱼哒粽子 2018-09-11
  • 打赏
  • 举报
回复
差点被你说懵逼,这一句“而类变量会先在构造器之前因为类初始化而初始化“,问题是代码里这就是一个final修饰的成员变量,并不是类变量,成员变量的初始化由构造器进行没问题吧?类变量的初始化随着类初始化进行,需要用static修饰才对。而且String不可以被改变,不等于String引用变量不能被改变,first始终保存的只是具体指向String对象的地址而已。
yoyocomeonbabygo 2018-09-10
  • 打赏
  • 举报
回复
首先string定义的值是可以改变的,其二,在person类中被final修饰的成员变量并没有被初始化,在构造方法中是对成员变量first进行了初始化。
若在定义成员变量的时候就对first进行了初始化,如public static final String first = “我是菜鸟”,此时就不能在构造方法中再次对fisrt成员变量进行赋值
verejava 2018-09-10
  • 打赏
  • 举报
回复
Java 面向对象 之 构造方法

http://www.verejava.com/?id=16992731753535
alunSemiconductor 2018-09-10
  • 打赏
  • 举报
回复
引用 5 楼 qq_20118831 的回复:
[quote=引用 4 楼 qq_40794696 的回复:]
public final String first;你这一段就不能通过编译,直接就报编译异常了,final修饰的变量必须在创建的时候就“显式”初始化!




如图,只要不用public修饰还是可以的因为public权限太大了[/quote]

你这里都直接把成员变量和局部变量混为一谈了,他这里的问题,具体请看#6我对上面这为朋友的回复。
alunSemiconductor 2018-09-10
  • 打赏
  • 举报
回复
引用 4 楼 qq_40794696 的回复:
public final String first;你这一段就不能通过编译,直接就报编译异常了,final修饰的变量必须在创建的时候就“显式”初始化!


你好,这里你搞错一个问题吧,final修饰的,只要在new对象的时候初始化就OK了,编译异常是要求你构造器里必须对这个变量赋值,而不是必须创建时赋值; 如果加上static的话,那就是常量了,那创建的时候确实必须赋值。
隐语者 2018-09-10
  • 打赏
  • 举报
回复
public final String first;你这一段就不能通过编译,直接就报编译异常了,final修饰的变量必须在创建的时候就“显式”初始化!
hetongfei 2018-09-10
  • 打赏
  • 举报
回复
这个是属于java设计者预留的一点小机制吗?
Surrin1999 2018-09-09
  • 打赏
  • 举报
回复
被final修饰的非static成员变量有三种初始化方式 第一种声明时赋值 你肯定知道 下面是其他两种



通过构造函数 同样可以为final成员变量赋值 前提是声明时没有赋值,且构造代码块中没有对其赋值



通过构造代码块 也可以为final成员变量赋值 前提是声明时没有赋值,且构造函数中没有对其赋值

同时使用构造函数和构造代码块对其赋值 就会在构造函数处报错 因为构造代码块是先于构造函数执行的 如下图所示



以下为测试代码


public class PersonTest {
final String a;

public PersonTest(String a) {
super();
this.a = a;
}

// {
// this.a = "这是被允许的";
// }

public static void main(String[] args) {
PersonTest p = new PersonTest("这也是被允许的");
// PersonTest p = new PersonTest();
System.out.println(p.a);
}
}

62,625

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧