有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java字符串:“字符串s=新字符串(“愚蠢”);”

我是一个C++学习java的家伙。我正在读有效的Java,有些东西把我弄糊涂了。它说永远不要写这样的代码:

String s = new String("silly");

因为它会创建不必要的String对象。但应该这样写:

String s = "No longer silly";

好的,到目前为止还不错。。。然而,鉴于这一类别:

public final class CaseInsensitiveString {
    private String s;
    public CaseInsensitiveString(String s) {
        if (s == null) {
            throw new NullPointerException();
        }
        this.s = s;
    }
    :
    :
}

CaseInsensitiveString cis = new CaseInsensitiveString("Polish");
String s = "polish";
  1. 为什么第一句话可以?难道不是吗

    CaseInsensitiveString cis = "Polish";

  2. 如何使CaseInsensitiveString的行为类似于String,这样上面的语句就可以了(有扩展String和没有扩展String)?字符串的什么特点使得它能够像这样传递一个文本?据我所知,Java中没有“复制构造函数”的概念


共 (6) 个答案

  1. # 1 楼答案

    String s1="foo";
    

    文字将进入池中,s1将引用

    String s2="foo";
    

    这一次,它将检查StringPool中是否已经存在“foo”文本,以便s2引用相同的文本

    String s3=new String("foo");
    

    首先在StringPool中创建“foo”文本,然后通过字符串arg构造函数创建字符串对象,即由于通过新操作符创建对象,因此在堆中创建“foo”,然后s3将引用它

    String s4=new String("foo");
    

    与s3相同

    所以System.out.println(s1==s2);// **true** due to literal comparison.

    System.out.println(s3==s4);// **false** due to object

    比较(s3和s4在堆中的不同位置创建)

  2. # 2 楼答案

    字符串在java中有点特殊,它们是不可变的,所以通过引用计数来处理它们是安全的

    如果你写信

    String s = "Polish";
    String t = "Polish";
    

    然后s和t实际上引用同一个对象,s==t将返回true,因为“==”for objects read“是同一个对象”(或者,无论如何,我不确定这是否是实际语言规范的一部分,或者只是编译器实现的一个细节,所以依赖它可能不安全)

    如果你写信

    String s = new String("Polish");
    String t = new String("Polish");
    

    然后是s=t(因为您已经显式创建了一个新字符串),尽管s.equals(t)将返回true(因为字符串将此行为添加到equals)

    你想写的东西

    CaseInsensitiveString cis = "Polish";
    

    无法工作,因为您认为引用是对象的某种短路构造函数,而实际上这只适用于普通的旧java。朗。字符串

  3. # 3 楼答案

    Java字符串很有趣。看起来这些回答涵盖了一些有趣的问题。这是我的两分钱

    字符串是不可变的(您永远无法更改它们)

    String x = "x";
    x = "Y"; 
    
    • 第一行将创建一个变量x,该变量将包含字符串值“x”。JVM将查看其字符串值池,查看“x”是否存在,如果存在,它将把变量x指向它,如果不存在,它将创建它,然后执行赋值
    • 第二行将删除对“x”的引用,并查看字符串值池中是否存在“Y”。如果它确实存在,它将分配它,如果它不存在,它将首先创建它,然后再分配。无论是否使用字符串值,字符串值池中的内存空间都将被回收

    字符串比较取决于所比较的内容

    String a1 = new String("A");
    
    String a2 = new String("A");
    
    • a1不等于a2
    • a1a2是对象引用
    • 当显式声明string时,将创建新实例,它们的引用将不同

    我认为您尝试使用不区分大小写的类是错误的。别管弦乐。您真正关心的是如何显示或比较值。使用其他类格式化字符串或进行比较

    TextUtility.compare(string 1, string 2) 
    TextUtility.compareIgnoreCase(string 1, string 2)
    TextUtility.camelHump(string 1)
    

    由于您正在组成类,因此可以让比较执行您想要的操作-比较文本值

  4. # 4 楼答案

    String在Java中是特殊的-它们是不可变的,字符串常量会自动转换为String对象

    您的SomeStringClass cis = "value"示例无法应用于任何其他类

    也不能扩展String,因为它被声明为final,这意味着不允许进行子分类

  5. # 5 楼答案

    我相信使用文本形式(即“foo”而不是新字符串(“foo”)的主要好处是,所有字符串文本都被VM“interned”。换句话说,它被添加到池中,这样创建相同字符串的任何其他代码都将使用池中的字符串,而不是创建新实例

    为了说明这一点,以下代码将打印第一行为true,第二行为false:

    System.out.println("foo" == "foo");
    System.out.println(new String("bar") == new String("bar"));
    
  6. # 6 楼答案

    String是该语言的一个特殊内置类。它只适用于String,在该类中,您应该避免说

    String s = new String("Polish");
    

    因为文字"Polish"已经是String类型,并且您正在创建一个额外的不必要的对象。对于任何其他类

    CaseInsensitiveString cis = new CaseInsensitiveString("Polish");
    

    这是正确的(在这种情况下也是唯一的)做法