final String相关问题

本文详细解析了Java中final关键字的使用场景及其限制,并通过具体示例深入探讨了String对象在不同创建方式下如何影响内存分配及引用比较的结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、final相关

final是”不可更改的”的意思,一般有以下几种用法:
1.修饰类
  当用final修饰一个类,那么这个类就不能被继承了
2.修饰方法
  该方法在子类中将不会被覆盖。
  住:类的private方法隐式的为final方法
3.修饰变量
  如果这个变量是基本类型(除了String),那么这个变量的值是不能改变的。如final int i=1;那么i是不能改变的。
  如果变量是个引用类型,那么引用不能改变,即这个引用不能指向其他的实例,但是实例的内容是可以改变的。

public class test {
    public static void main(String args[]){
    final A a1=new A();
    A a2=new A();//a1=a2;错误
    System.out.println("k="+a1.k);
    a1.k++;
    System.out.println("k="+a1.k);
    }
}

class A{
    int k;
}

二、String相关

  String有两种创建的方式:

  String str=new String("hello world!");
 String str="hello world!";

第一种方式创建的字符串,引用str放在栈里面,字符串”hello world!”放在堆里面。
第二种方式创建的字符串,创建的”hello world!”放在常量池中,并返回引用给str。


在常量池中,只保存一个对象,即若s1=”dd”;s2=”dd”.那么常量池中只有一个”dd”,s1,s2都指向”dd”.


三、final String相关问题

先看一段代码:

public class test {
    public static void main(String args[]){
     String s1="helloworld";
     String s2="hello";
     final String s3="hello";
     String s4=s3+"world";
     String s5=s2+"world";
     System.out.println((s1==s4));
     System.out.println(s1==s5);
    }
}

运行的结果是:

true
false

为什么会这样呢???
  首先s1,s2,s3都是在常量池的。其中s3是一个常量,因为它被final修饰,在编译阶段,就可以确定s3的值就是”hello”,所以遇到s3,就直接替换成”hello”。所以s4=”hello”+”world”=”helloworld”,而且存放在常量池,所以s4和s1是同一个字符串的引用,所以s1==s4为true。而s5=s2+”world”,这种形式,s2是一个变量,不管是不是在常量池中,都会在堆上创建一个s2,然后再和”world”拼接,这样形成一个新的对象,s5是新对象的引用,这样s5是在堆上面,而s1在常量池中,所以指向的不是同一个对象,故为false。
  

再看一段代码,思考结果是什么?

public class test {
    public static void main(String args[]){
     A a=new A();
     a.print();
    }
}

class A{
    final String s;
    public A(){s="hello";}
    public void print(){
        String str="helloworld";
        String s1="world";
        String s2=s+s1;
        System.out.println(s2==str);
    }
}

  
结果为false。为什么???

再看一段代码:

public class test {
    public static void main(String args[]){
     A a=new A();
     a.print();
    }
}

class A{
    final static String s;
    static {
        s="hello";
    }
    public A(){}
    public void print(){
        String str="helloworld";
        String s1="world";
        String s2=s+s1;
        System.out.println(s2==str);
    }
}

结果也是false

前面不是说,遇到final可以直接进行替换吗??
  当字符串在类的构造器中赋值或在静态块中赋值,无法在编译时确定这个变量是不是来自常量池,所以会在堆上创建这个对象,所以两者的结果都是false。
  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值