Java has a value type?


Some people read the article before me, " Swift language of design errors ," and asked me: "You say Java only reference types (reference type), but according to Java's official documentation , Java is also different value types (value type) and reference types of, such as int, boolean and other primitive type is a value type. "now let me explain this problem.

Java has a value type, primitive type int, boolean, etc. are value types, is actually a long-standing misunderstanding, it confuses the distinction between implementation and semantics. Do not think that Java is the official document that is written authoritative conclusion, we can say, "Wang Yin do not understand," Wang Yin :) do not know when a primary issue when you think, you need to think twice, because he probably gave me a knowing too much ...... the following discussion, you might find yourself should doubt that, Java designers in the end there is not thoroughly understand this problem: P

Craps end, for now get down to business. Primitive type of Java, Scheme and other languages, such as char, int, boolean, double, etc., in the "realization" is indeed a value (rather than a reference, or call pointer) passed on directly, but it is a completely efficient in order optimization (called the inlining). This optimization for programmers should not be visible. Java inherits the Scheme / Lisp mantle, they are on the "semantics" is actually not a value type.

This is not a fairy tale, in order to understand this, you can make a very interesting thought experiment. Now you put inside all Java primitive types "Imagine" as a reference type, that is to say, all of the original type int, boolean variables do not contain the actual data, but references (aka pointer), pointing to the heap data distribution. Then you will find this "post-reform" of Java, the phenomenon is still in line with all existing Java code can be seen. In other words, the original type is used as a value type or reference type, there is no difference for the programmer.

As a simple example, if we realize int into a complete reference, and then look at the code:

int x = 1;    // x指向内存地址A,内容是整数1
int y = x;    // y指向同样的内存地址A,内容是整数1
x = 2;        // x指向另一个内存地址B,内容是整数2。y仍然指向地址A,内容是1。
复制代码

Since Java int inside after we transform all references, so the first line of the definition xdoes not contain an integer, but a reference that points to a heap memory allocated, this space is the integer 1. In the second line, we will be int variables y, of course, it is also a reference to its value with xthe same, so yalso point to the same address, the contents of which are the same integer: 1. In the third line, we xquote this assignment. You will find a very interesting phenomenon, although xpointing to the 2, ybut still point to 1. For xthe assignment did not change the ycontent point, this situation is exactly the same as the value of the type just like int time! So now, although int variables are all cited, but you can not achieve the shared address references can do: to xcarry out a certain operation, resulting in ycontent point also changed.

The reason for this phenomenon is that although it has become a reference type int, but you and it can not be a reference type specific (but not the type of value) of operation. Such operations include:

  1. deref. Like the C language *operators.
  2. Members of the assignment. Like members of the C struct x.foo = 2.

In Java, you can not write like the C language *x = 2such code, because Java does not provide deref operator *. You can not pass x.foo = 2such a sentence changes xportion at the memory data (content 1), because int is a primitive type. Finally, you find that you can only write x = 2, that is, to change xthe references to itself. x = 2After execution, the memory space where the original number 1 and 2 did not become, but point to a new address x, where the number 2 filled with it. Links to other reference variables such as 1 y, not because you had x = 2this operation and see two, they still see the original 1 ......

This is a reference to the Java int's, you are int variables xthing can do only two:

  1. Read its value.
  2. Its assignment, it points to another place.

These two things, just like you can not distinguish between two things of value types do. That's why you can not pass on the xchanged operational yvalue representation. Therefore, regardless of the int is achieved in the transfer or passing a reference value, they are semantically equivalent. In other words, the original type is a value type or reference type, the programmer no difference. You can put all the Java primitive types want to be a reference type, then you can do for them, your programming ideas and methods, and therefore will not have any change.

From this standpoint, Java value type is not semantically. If the value types and reference types coexist, programmers must be able to feel the difference in their semantics, but regardless of the original type is a value type or reference type, as a programmer, you can not feel any different. So you can only think Java reference types, all of the original type as a reference type to use, although they do is of value realization.

A value type of language (such as C #, Go and Swift) semantically must have one of the following two characteristics (or both), programmers can feel the presence of a value type:

  1. deref operation. This allows you to use *x = 2this statement to change the point of reference content, resulting in other references to shared addresses see the new value. You can not pass x = 2let the other get the new value of the variable value, so you feel there is value type.
  2. Like struct "type value combinations." You can x.foo = 2change a part of reference data (such as class object) of the members of such an assignment, making the shared address other references to see the new value. You can not let another assignment by members of the struct variable to get the new value, so you feel there is value type.

In fact, all the data are reference types and Java Scheme is the original design principles. A primitive type value to pass only a performance optimization data (called the inlining), it should be transparent to the programmer (not visible) of. In the interview to ask those who like "Java if all the data is referenced," and then when you answer "yes" to correct you say "int, boolean value type" of people, who are book worship.

Questions

It was pointed out, Java reference types can be null, but not the original type, so reference types and value types or different. But in fact, this does not deny the article pointed out that point of view, you may think this is why?


Guess you like

Origin juejin.im/post/5dfdbcf25188251235094a99