java 为什么java有“String”类型而不是“string”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2108828/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 19:30:09  来源:igfitidea点击:

Why java has "String" type and not "string"?

javastringprimitive-typesreference-type

提问by Ravi Gupta

Wrapper class are just fine and their purpose is also well understood. But why do we omit the primitive type ?

包装类很好,它们的目的也很好理解。但是为什么我们省略了原始类型?

回答by Robert Fraser

It depends what you mean by "primitive"

这取决于你所说的“原始”是什么意思

"Primitive" in Java is usually taken to mean "value type". However, C# has a stringkeyword, which acts exactly the same as Java's String, it's just highlighted differently by the editor. They are aliases for the classes System.Stringor java.lang.String. String is not a value type in either language, so in this way it's not a primitive.

Java 中的“原始”通常表示“值类型”。但是,C# 有一个string关键字,其作用与 Java 的 String 完全相同,只是编辑器对其突出显示不同。它们是类System.String或 的别名java.lang.String。字符串在任何一种语言中都不是值类型,因此在这种情况下它不是原始类型。

If by "primitive" you mean built into the language, then String is a primitive. It just uses a capital letter. String literals (those things in quotes) are automatically converted to System.Stringand + is used for concatenation. So by this token, they (and Arrays) are as primitive as ints, longs, etc.

如果“原始”是指内置于语言中,那么 String 是原始的。它只使用大写字母。字符串文字(引号中的内容)会自动转换为System.String+ 用于连接。因此,根据这个标记,它们(和数组)与 int、long 等一样原始。

First, what is a String?

首先,什么是字符串?

String is not a wrapper. String is a reference type, while primitive types are value types. The means that if you have:

字符串不是包装器。字符串是引用类型,而原始类型是值类型。这意味着,如果您有:

int x = 5;
int y = x;

The memory of x and y both contain "5". But with:

x 和 y 的内存都包含“5”。但与:

String x = "a";
String y = x;

The memory of x and y both contain a pointerto the character "a" (and a length, an offset, a ClassInfo pointer, and a monitor). Strings behave like a primitive because they're immutable, so it's usually not an issue, however if you, say, used reflection to change the contents of the string (don't do this!), both x and y would see the change. In fact if you have:

x 和 y 的内存都包含一个指向字符“a”的指针(以及一个长度、一个偏移量、一个 ClassInfo 指针和一个监视器)。字符串表现得像一个原语,因为它们是不可变的,所以这通常不是问题,但是如果你说,使用反射来改变字符串的内容(不要这样做!),x 和 y 都会看到变化. 事实上,如果你有:

char[] x = "a".toCharArray();
char[] y = x;
x[0] = 'b';
System.out.println(y[0] == 'b'); // prints "true"

So don't just use char[] (unless this is the behavior you want, or you're reallytrying to reduce memory usage).

所以不要只使用 char[] (除非这是你想要的行为,或者你真的想减少内存使用)。

Every Objectis a reference type -- that means all classes you write, every class in the framework, and even arrays. The only things that are value types are the simple numeric types (int, long, short, byte, float, double, char, bool, etc.)

EveryObject是引用类型——这意味着您编写的所有类、框架中的每个类,甚至数组。唯一的值类型是简单的数字类型(int、long、short、byte、float、double、char、bool 等)

Why isn't String mutable like char[]?

为什么 String 不像 char[] 那样可变?

There are a couple reasons for this, but it mostly comes down to psychology and implementation details:

这有几个原因,但主要归结为心理学和实施细节:

  • Imagine the chaos you'd have if you passed a string into another function and that function changed it somehow. Or what if it saved it somewhere and changed it in the future? With most reference types, you accept this as part of the type, but the Java developers decided that, at least for strings, they didn't want users to have to worry about that.
  • Strings can't be dealt with atomically, meaning multithreading/synchronization would become an issue.
  • String literals (the things you put in your code in quotes) might be immutable at the computer's level1(for security reasons). This could be gotten around by copying them all into another part of memory when the program starts up or using copy-on-write, but that's slow.
  • 想象一下,如果您将一个字符串传递给另一个函数,而该函数以某种方式改变了它,您会遇到什么样的混乱。或者如果它把它保存在某个地方并在将来改变它呢?对于大多数引用类型,您接受它作为类型的一部分,但 Java 开发人员决定,至少对于字符串,他们不希望用户担心这一点。
  • 字符串不能以原子方式处理,这意味着多线程/同步将成为一个问题。
  • 字符串文字(您在代码中用引号引起来的内容)在计算机的1级(出于安全原因)可能是不可变的。这可以通过在程序启动时将它们全部复制到内存的另一部分或使用写时复制来解决,但这很

Why don't we have a value-type version of a string?

为什么我们没有字符串的值类型版本?

Basically, performance and implementation details, as well as the complexity of having 2 different string types. Other value types have a fixed memory footprint. An int is always 32 bits, a long is always 64 bits, a bool is always 1 bit, etc.2Among other things, this means that they can be stored on the stack, so that all parameters to a function live in one place. Also, making gigantic copies of strings all over the place would kill performance.

基本上,性能和实现细节,以及具有 2 种不同字符串类型的复杂性。其他值类型具有固定的内存占用。int 始终为 32 位,long 始终为 64 位,bool 始终为 1 位,等等。2除此之外,这意味着它们可以存储在堆栈中,因此函数的所有参数都位于一个位置. 此外,在各处制作巨大的字符串副本会降低性能。

See also: In C#, why is String a reference type that behaves like a value type?. Refers to .NET, but this is just as applicable in Java.

另请参阅:在 C# 中,为什么 String 是行为类似于值类型的引用类型?. 指 .NET,但这在 Java 中同样适用。

1 - In C/C++ and other natively-compiled languages, this is true because they are placed in the code segment of the process, which the OS usually stops you from editing. In Java, this is actually usuallyuntrue, since the JVM loads the class files onto the heap, so you could edit a string there. However, there's no reason a Java program couldn't be compiled natively (there are tools which do this), and some architectures (notably some versions of ARM) dodirectly execute Java bytecode.

1 - 在 C/C++ 和其他本地编译的语言中,这是正确的,因为它们被放置在进程的代码段中,操作系统通常会阻止您进行编辑。在 Java 中,这实际上通常是不正确的,因为 JVM 将类文件加载到堆上,因此您可以在那里编辑字符串。但是,没有理由不能本地编译 Java 程序(有一些工具可以做到这一点),并且某些架构(特别是某些 ARM 版本)确实直接执行 Java 字节码。

2 - In practice, some of these types are a different size at the machine level. E.x. bools are stored as WORD-size on the stack (32 bits on x86, 64 bits on x64). In classes/arrays they may be treated differently. This is all an implementation detail that's left up to the JVM -- the spec says bools are either true or false and the machine can figure out how to do it.

2 - 实际上,其中一些类型在机器级别具有不同的大小。Ex bool 以 WORD 大小存储在堆栈中(x86 上为 32 位,x64 上为 64 位)。在类/数组中,它们可能会被区别对待。这是留给 JVM 的所有实现细节——规范说 bool 要么是真要么是假,机器可以弄清楚如何去做。

回答by Oded

The primitive type for Stringis char[].

的原始类型Stringchar[]

This is true for many languages (C, Java, C#, C++ and many more...).

这适用于许多语言(C、Java、C#、C++ 等等……)。

回答by Aadith Ramia

strings could be of arbitrary length. the fathers of java did not want to have a primitive type for which they could not assign a concrete memory size. this is one of the chief reasons string is not a primitive in java.

字符串可以是任意长度。Java 之父不想拥有一个无法为其分配具体内存大小的原始类型。这是 string 在 java 中不是原语的主要原因之一。

回答by helios

Primitive?

原始?

If Java there's no primitive for strings. The primitives are int, float, double, boolean, etc... and char.

如果 Java 没有字符串的原语。原语是 int、float、double、boolean 等……和 char。

So for using strings they've used an object. You instance it, it lives in the heap, you have a reference to it, etc.

所以为了使用字符串,他们使用了一个对象。你实例化它,它存在于堆中,你有一个对它的引用,等等。

How did they implement it? Saving the value it represents in a char array.

他们是如何实施的?将它代表的值保存在一个字符数组中。

Inmutability

不变性

But they ensured inmutability. When you have a reference to a String object you knowyou can pass it freely to other objects knowing the value pointed by that reference will not change. All methods that modifies strings returns other instance of the string so it doesn't change the value represented by other references to String.

但它们确保了不变性。当您拥有对 String 对象的引用时,您知道您可以自由地将它传递给其他对象,并且知道该引用指向的值不会改变。所有修改字符串的方法都返回字符串的其他实例,因此它不会更改其他对 String 的引用所表示的值。

Can it be other way (like in .Net)

可以是其他方式吗(比如在 .Net 中)

Yes. They could have defined a reserved word stringand the compiler do the transformation.

是的。他们可以定义一个保留字串,然后编译器进行转换。

But they didn't...

但他们没有...

回答by thecoop

String is sort of a special case. All the real primitive types (int, long, etc) are pass-by-value, and implemented directly in the JVM. String is a reference type, and so dealt with like any other class (capital letter, pass-by-reference...), except the compiler has special hooks to deal with it like a built-in type (+ for string concatentation, for example).

字符串是一种特殊情况。所有真正的原始类型(int、long 等)都是按值传递的,并直接在 JVM 中实现。String 是一种引用类型,因此像任何其他类一样处理(大写字母,传递引用......),除了编译器有特殊的钩子来像内置类型一样处理它(+ 表示字符串连接,例如)。

As it is already a reference type, it does not need a wrapper class like Integer to be able to use it as a class (in collections, for example)

因为它已经是一个引用类型,所以它不需要像 Integer 这样的包装类就可以将它用作类(例如在集合中)

回答by Pierre

a String is an array of char. As it is an array, it cannot be a primitive ! :-)

String 是一个字符数组。因为它是一个数组,所以它不能是一个原始的!:-)