以下陈述有什么区别
String name = "Tiger";
final String name ="Tiger";
虽然String
类是final
类,但为什么我们需要创建一个字符串“CONSTANT”变量作为final?
final
在这种情况下,意味着变量name
只能分配一次。再次为其分配不同的String
对象会导致编译错误。
我认为这里混乱的根源是final
关键字可以在几种不同的上下文中使用:
有关每种情况的示例,请参阅有关Java 中 final的 Wikipedia 文章。
“最终”在两种情况下的含义不同。
java.lang.String 类是最终的。这意味着你不能继承它。
变量“name”是最终的,这意味着您不能将其更改为指向不同的 String 实例。因此,非最终字符串变量不是常量,因为您可以在两次不同的时间读取它并获得不同的值。
碰巧的是,Java 字符串对象也是不可变的。这意味着您不能修改特定 String 对象所代表的值。将此与数组进行比较 - 您可以将数组对象的第一个元素替换为不同的对象,但不能将 String 对象的第一个字符替换为不同的字符。这就是 String.replace() 返回一个新字符串的原因——它不能修改旧字符串。
String 是 final 的一个原因是为了防止 String 的子类的实例(它实现了可变行为)被传递来代替 String。
但是是否可以修改特定的对象,以及是否可以将不同的对象分配给变量,是完全不同的概念。一个是 String 对象的属性,另一个是 String 变量的属性,是对 String 对象的引用。
请记住,Java final 关键字在这种情况下有两个用途:
您将 immutable 与 final 混淆了。
String 与 Integer 和 Long 一样,是一个不可变的类,因为内部数据通过封装被保护不被修改。
但是,就像 Ayman 所说,final 指的是指向字符串的指针。
String name = "scott";
name = "tiger"; // OK
final String gender = "male";
gender = "female"; // won't compile you cannot reassign gender cause it's final
如果一个变量被标记为final,那么该变量的值就不能改变,即当与变量一起使用时final关键字使其成为一个常量。如果您在程序执行过程中尝试更改该变量的值,编译器会给您一个错误。
注意: 如果将引用类型的变量标记为 final,则该变量不能引用任何其他对象。但是,您可以更改对象的内容,因为只有引用本身是最终的。
来源:Java 中的最终关键字
推断 String 对象默认为 Final 本身就是一个模糊的陈述。Java 的基础规定,如果一个实例变量没有指向一个内存位置,它就有资格进行垃圾收集。String 对象也会发生同样的事情。它们是不可变的,但它们的引用可以更改。为了克服这个问题,我们可以使用 "Final String s1 = "Final String" " 关键字不允许对 s1 进行任何赋值,除非在首次声明时,使其真正不可变。
public class DemoStringF
{
String s1; //Declaring an Instance Variable to type String.
public static void main(String... args)
{
DemoStringF d = new DemoStringF ();
d.s1 = "Intializing s1 here"; //Initializing the s1
System.out.println("Value ref. by s1 is " +d.s1); //Displays the String
by which s1 is
initialized.
System.out.println("Value of s1 is " +d.s1.hashCode()); //Displays the
value of the s1.
d.s1 = d.s1.concat(" Adding String to s1"); //Changing the value ref. by
s1.
System.out.println("Value ref. by s1 after concat() is " +d.s1);
//Displays a new value of s1.
System.out.println("Value of s1 is " +d.s1.hashCode()); //Displays
the value of the s1.
}
}