2
val hello1 = "hello"
val hello2 = "hello"
printf(hello1 === hello2)

why print true?

I guess kotlin has a primitive type pool(or something like that). If the value is equality,a pointer points to same place.I'm not sure.

Shawn Plus
  • 457
  • 1
  • 6
  • 15
  • 1
    Note that `String` is not a primitive type. – Jesper Oct 24 '17 at 06:33
  • even so why get true, i thought only primitive type – Shawn Plus Oct 24 '17 at 08:06
  • Because `===` compares references, and just like in Java, there is a string pool - string literals are shared in the pool, so if you have two string literals with the same content then there is only one `String` object and both your variables point to the same object. – Jesper Oct 24 '17 at 11:28
  • I mean val a1 =1 val a2=1 print(a1 === a2) get ture, why? there is a Integer pool? – Shawn Plus Oct 25 '17 at 00:58
  • No. In that example `a1` and `a2` are not `Integer` objects, they are just primitive values - not objects. `===` just compares the values. Exactly the same as what `==` does in Java. – Jesper Oct 25 '17 at 05:56
  • if write val a1:Int =1 val a2:Int =2 , they are still primitive values? How to judge a object or primitive – Shawn Plus Oct 25 '17 at 07:59
  • There is a [fixed set of primitive types](https://kotlinlang.org/docs/reference/basic-types.html): Double, Float, Long, Int, Short, Byte, Char, Boolean. Those are primitive types, any other type is not. – Jesper Oct 25 '17 at 08:05

3 Answers3

6

a string literal always refers to the same instance of class String. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern.

Kotlin simply reuses the same mechanism. See Is String Literal Pool a collection of references to the String Object, Or a collection of Objects and Java String literal pool and string object for additional explanations.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
4

Equality in Kotlin

I explained the general equality tools used in Kotlin in this answer. TLDR:

  1. structural equality: == is compiled to Java's equals

  2. Referential equality: === is what == does in Java: References are compared to each other. It yields true if the same objects are being compared.

What about Strings like in your example?

Strings are special in that they work with a so called string constant pool. For example, even in Java, the following is true for both comparisons:

public static void main(String[] args) {
    String s = "prasad";
    String s2 = "prasad";

    System.out.println(s.equals(s2));
    System.out.println(s == s2);
}

On the other hand, the next snippet does work differently since new Strings are being created:

String foo = new String("hello");
String bar = new String("hello");
System.out.println(foo == bar);  // prints 'false'

Read about it here: What is the Java string pool and how is "s" different from new String("s")?

FYI: Strings are not primitive.

s1m0nw1
  • 76,759
  • 17
  • 167
  • 196
2

https://kotlinlang.org/docs/reference/equality.html

In Kotlin there are two types of equality:

  • Referential equality (two references point to the same object);
  • Structural equality (a check for equals()).

Referential equality is checked by the === operation (and its negated counterpart !==). a === b evaluates to true if and only if a and b point to the same object.

Structural equality is checked by the == operation (and its negated counterpart !=). By convention, an expression like a == b is translated to:So you see

a?.equals(b) ?: (b === null)

So you see: == means equals and === means referential equality

That would imply that

val hello1 = "hello"
val hello2 = "hello"
printf(hello1 === hello2)

is referential compared which should lead to false. BUT: When you use a string literal like "hello", the string cache of java is used (this is an optimization to save memory). So you get both times the same reference, and therefore the reference equality is true.

guenhter
  • 11,255
  • 3
  • 35
  • 66
  • Kotlin has no primitive type? I only saw Int,Boolean,Double... <- class – Shawn Plus Oct 25 '17 at 02:51
  • Kotlin do have primitives, but the compiler decides when to use it and when to use the wrapper types. so `Int`, `Boolean`, ... will be compiled to primitive types in the bytecode in most situations (when they are not involved in generics or you use the nullable-variant of the type `Int?`) – guenhter Oct 25 '17 at 04:52