Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java函数中静态常量char*的等价性_Java_C++ - Fatal编程技术网

java函数中静态常量char*的等价性

java函数中静态常量char*的等价性,java,c++,Java,C++,我经常在C++中使用这个成语: /*return type*/ foo(/*parameters*/){ static const char* bar = "Bar"; /*some code here*/ } 在内部,它被添加到字符串文本表中。这段Java代码是否做了类似的事情: /*return type*/ foo(/*parameters*/){ final String bar = "Bar"; /*some code here*/ } 还是我无意中

我经常在C++中使用这个成语:

/*return type*/ foo(/*parameters*/){
    static const char* bar = "Bar";
    /*some code here*/
}
在内部,它被添加到字符串文本表中。这段Java代码是否做了类似的事情:

/*return type*/ foo(/*parameters*/){
    final String bar = "Bar";
    /*some code here*/
}

还是我无意中在这里引入了低效率?

字符串在Java中是不可变的。这意味着您不必给出提示,就可以让JVM知道它不会改变并优化它


字符串文本被扣留以避免冗余,这意味着它们已经“添加到字符串文本表中”。这里不需要使用
final

您可以通过调用
string.intern()
指定要添加到文本池的字符串(在Java中称为interning),如下所示:

final String bar = myString.intern();
它基本上与文本池的概念相同,对给定字符串使用相同的对象。请注意,字符串文字是自动插入的。它还允许您通过引用比较插入的字符串,因此它可能更有效。但是,必须始终比较通过
intern()
返回的字符串。因此

a.equals(b);
可以用

a.intern() == b.intern();

请注意,您实际上并不希望完全按照所描述的那样执行上述操作。理想情况下,您可以保留插入的字符串并重用它们。然而,内接字符串存在一些陷阱。它们不是垃圾收集的,而且方法本身有点昂贵

Java方法中的
final
关键字与您认为的不同

在这种特殊情况下,
final
使变量不可修改。就这样。内容本身确实会添加到字符串常量的全局表中,但从技术上讲,每次都会设置指向它的指针(请原谅术语)


final
关键字主要用于在方法中使变量可用于在其之后创建的任何匿名类。它是java的小便,他们对他们喜欢“关闭”的支持缺乏支持。这也是从内部匿名类中访问外部变量的唯一方法

final String bar = "Bar";
final Set<String> allTheBars = new HashSet<>() {{
    add(bar);
}};
final String bar=“bar”;
最终设置allTheBars=新哈希集(){{
添加(条);
}};

我认为您的解决方案是正确的,它们几乎与Java所能表达的等价

正如其他答案所提到的,字符串是不可变的,final没有添加任何性能增强,但是我觉得final在语义上是有用的。很像C++中的“const”;“final”确保值不能更改,并且尝试这样做将导致编译器错误-在我看来,这在您的情况下是一种可取的行为


(与C++ const一样多),它可能导致一些可能不被考虑的优化。

如果关闭不能修改状态,则对您(和JIT)更好。因此,我不会称之为“撒尿穷人”。@Ingo很公平,也许是“不一致的”。您可以毫无问题地修改最外层类的变量(使用ClassName.this.varName),但您不能对附近的变量做任何事情。-1 final是java语言的一个重要部分,在许多上下文中对许多不同的事情都很有用(密封类,确保常量保持不变,允许对局部变量进行闭包等)你对结构的情绪化批评对提问者没有什么帮助或帮助。@Chris更糟糕的是,你可以通过
final
引用修改状态,如
final int[]foo=new int[]{42};new Runnable(){void run(){foo[0]=43;}}
@Elemental我有没有说它不重要?第一段解释了用法,第二段在原始上下文中解释了为什么final关键字对OP不太有用(同样,在原始上下文中)。我称之为“尿贫”,因为在这种情况下它是尿贫。我不是情绪化,我只是告诉OP其他语言的功能远远好于Java。在里面这在字符串文本上使用
intern()
是没有用的@是的,我知道。我需要一个更好的例子。函数静态变量可能没有您想象的那么有效,有可能每次调用函数时生成的代码都在检查它是否已初始化。虽然在这种情况下,它可能会被优化。不完全是
final
防止修改字符串引用以指向不同的字符串,因此如果您想要一个真正的常量字符串,它应该是
final