String values in Kotlin - kotlin

In Java, if we do new String() we know it would create new string object and it would be different from the object created without 'new'(even if contents are same).
//Java
System.out.println("First" == new String("First")); // false always
In Kotlin, if I try to create String even by creating StringBuilder, it would still be identical to that created without String(..).
//Kotlin
println("First" == String(StringBuilder("First"))) //true always
If the created String(StringBuilder(..)) is going to reuse same string value, why give constructor? Does it do any value add, looking for such use-case.
Thanks.

By using the == operator you're checking structural equality between the strings (whether they represent the same sequence of characters). The Java equivalent of your Kotlin comparison code above would be something like this:
Object.equals("First", new String(new StringBuilder("First"))); // true
To check reference equality in Kotlin, you need to use the === operator.
Check out the Kotlin reference on Equality.

In Java when you use operator == you use referential equality. However, in Kotlin it is structural equality.
To use referential equality in Kotlin you need to use === operator.
You can check this doc page for more information: https://kotlinlang.org/docs/reference/equality.html

To use referential equality you need to use === operator in kotlin.
In java == operator use for referential equality. but in kotlin it is structural equality.

In Java, == is referential equality, but in Kotlin == is structural equality. That means, in Kotlin == and string1.equals(string2) both do the same thing. And in Kotlin we use === for referential equality.

Related

Kotlin Operators ?, ?., ?: open source implementation

I am pretty new to Kotlin, I am looking at the null safety and Elvis operators and would like to know more on how these are implemented to work on top of JVM.
Operators I am interested to know the implementation of:
? ?. ?:
But I am unable to locate any source associated with these. Are the implementations hidden? From my IDE also I cannot locate any source related to these, magic?
From the Kotlinlang.org: It specifies that Kotlin is an open source language: Kotlin is an open-source statically typed programming language that targets the JVM, Android, JavaScript and Native
Note: I know I don't need to specify null on the right hand side of the Elvis, this is just to send my point across in the screen grab.
Disclaimer: I'm no expert on the Kotlin compiler. I just looked at the source code.
The tokens are defined here:
KtSingleValueToken SAFE_ACCESS = new KtSingleValueToken("SAFE_ACCESS", "?.");
KtSingleValueToken ELVIS = new KtSingleValueToken("ELVIS", "?:");
KtSingleValueToken QUEST = new KtSingleValueToken("QUEST", "?");
These tokens are parsed by the Kotlin compiler itself, they are not defined in Java. This is why you cannot jump to a definition - they are re-written by the compiler.
I don't know how they are implemented, but checking out the Kotlin source and using the above tokens as a starting point might be useful.
Those features are "embedded" into the language. So you can't really dig into the code at compile time. An equivalent example to this would be trying to get the implementation of a while loop or a when statement. Those are language features that just generate compiled code
One thing that you could do if you're curious would be to decompile a simple program using them and check the result. However, as the generated bytecode may include some optimizations, the result might differ between different use cases.
The most important thing you need to know is what they do and how to use them. You can find an example of equivalent behaviour between null safe operators and java code in the Kotlin Koans, in which this Java code
public void sendMessageToClient(
#Nullable Client client,
#Nullable String message,
#NotNull Mailer mailer
) {
if (client == null || message == null) return;
PersonalInfo personalInfo = client.getPersonalInfo();
if (personalInfo == null) return;
String email = personalInfo.getEmail();
if (email == null) return;
mailer.sendMessage(email, message);
}
can be rewritten in Kotlin as
val email = client?.personalInfo?.email
if (email != null && message != null) {
mailer.sendMessage(email, message)
}
You don't have to set null on the right side of the elvis operator, the elvis operator is for handling non nullable case.
val info:EuiccInfo? = msg?.euiccInfo
val info - defined as nullable so it can be set null as well, if msg is null (msg? means msg can be null too, and if msg is null it will not access to .euiccInfo) info will be null.
lets assume info defined as non nullable val
val info:EuiccInfo = msg?.euiccInfo
compiler will not allow you to set info null value because msg is nullable,
so you have to handle non null case.
val info: EuiccInfo = msg?.euiccInfo ?: someDefaultNonNullValue (EuiccInfo())
it's unnecessary (and nonsense) to handle null case with Elvis operator because it will be set null if msg is null or msg?.euiccInfo is null.

Unexpected result when comparing CharSequence.reversed() return value

Have noticed a strange behavior when comparing a result of CharSequence.reversed() method.
val s = "a"
val subSequence = s.subSequence(0, 1)
println("$subSequence == ${subSequence.reversed()}: ${subSequence == subSequence.reversed()}")
Results in:
a == a: false
Moreover subSequence.reversed() == subSequence.reversed() is also false.
Can someone explain this unexpected behavior?
CharSequence is actually an interface which classes like String and StringBuilder implements. The reason why the result of subSequence(0, 1) isn't equal to subSequence.reversed() is because of the actual types they return.
The subSequence(0, 1) call returns a String, while reversed() returns a StringBuilder. The equals-method will therefore return false because the types are different.
It will work as you would expect if you call toString() on the result of reversed():
val reversed = subSequence.reversed().toString()
println("$subSequence == $reversed: ${subSequence == reversed}") // Prints a == a: true
Converting back to a String fixes the issue because then the correct (expected) eqauals is applied:
val s = "a"
val subSequence = s.subSequence(0, 1)
println(subSequence.reversed() == subSequence.reversed()) //false
println(subSequence.reversed().toString() == subSequence.reversed().toString()) //true
Note that you are probably confused by what is shown by toString and how equality (equals) behaves.
What you see is the output of toString(). Any type can decide how it's object's string representation might look like by overriding that method. This however has no influence on how objects of that type are compared against each other. That is where equals (in some cases also compare) comes in.
Others wrote something about that the underlying type of the objects to compare isn't equal (one side StringBuilder and the other String). The actual problem however is that of the equals-method. It could be (usually it isn't done so for various reasons), that equals for a certain type supports equality of different types of objects (such a behaviour (would) should be mentioned in the interface at least). If nothing is specified one can assume that the default equality from Object.equals holds.
In this case however the CharSequence-javadoc already states the following about equality (emphasis mine):
This interface does not refine the general contracts of the equals and hashCode methods. The result of testing two objects that implement CharSequence for equality is therefore, in general, undefined. Each object may be implemented by a different class, and thereis no guarantee that each class will be capable of testing its instancesfor equality with those of the other. It is therefore inappropriate to usearbitrary CharSequence instances as elements in a set or as keys ina map.
So summarizing: forget that you got a String or StringBuilder from subSequence and reversed. The method contract specifies CharSequence and as such you must handle it as CharSequence. There is no guarantee that those functions will still return a String or StringBuilder in future.

What is the difference between not-null checks in Kotlin?

There are some ways to fulfill a null-checking in Kotlin:
1.
if(myVar != null) {
foo(myVar)
}
2.
myVar?.let {
foo(it)
}
3.
myVar?.run {
foo(this)
}
What are the difference between these ways?
Are there any reasons (performance, best practice, code style etc.) why I should prefer on way over the other?
!! is to tell the compiler that I am sure the value of the variable is not null, and if it is null throw a null pointer exception (NPE) where as ?. is to tell the compiler that I am not sure if the value of the variable is null or not, if it is null do not throw any null pointer.
Another way of using a nullable property is safe call operator ?.
This calls the method if the property is not null or returns null if that property is null without throwing an NPE (null pointer exception).
nullableVariable?.someMethodCall()
All three code are behave same null check in operation-wise.
?. is used for chain operations.
bob?.department?.head?.name // if any of the properties in it is null it returns null
To perform a chain operation only for non-null values, you can use the safe call operator together with let
myVar?.let {
foo(it)
}
the above code is good for code style and performance
more details refer Null Safety
The ways 2 and 3 are more idiomatic for Kotlin. Both functions are quite similar. There is little difference with argument passing.
For example, we have a nullable variable:
var canBeNull: String? = null
When you working with T.run you work with extension function calling and you pass this in the closure.
canBeNull?.run {
println(length) // `this` could be omitted
}
When you call T.let you can use it like lambda argument it.
canBeNull?.let {
myString -> println(myString.length) // You could convert `it` to some other name
}
A good article about Kotlin standard functions.
All three are roughly equivalent.
The if case is more like most other languages, and so many developers may find it easier to read.
However, one difference is that the if case will read the value of myVar twice: once for the check, and again when passing it to foo(). That makes a difference, because if myVar is a property (i.e. something that could potentially be changed by another thread), then the compiler will warn that it could have been set to null after the check. If that's a problem (e.g. because foo() expects a non-null parameter), then you'll need to use one of the other cases.
For that reason, the let case has become fairly common practice in Kotlin. (The run case does just about the same thing, but for some reason isn't as popular for this sort of thing. I don't know why.)
Another way around it is to assign myVar to a temporary value, test that, and then use that. That's also more like other languages, but it's more verbose; many people prefer the conciseness of the let case — especially when myVar is actually a complicated expression.
The examples in your question don't show the true reason to decide.
First of all, since you're not using the return value of foo, you should use neither let nor run. Your choice is between also and apply.
Second, since you already have the result you want to null-check in a variable, the difference fades. This is a better motivating example:
complexCall(calculateArg1(), calculateArg2())?.also {
results.add(it)
}
as opposed to
val result = complexCall(calculateArg1(), calculateArg2())
if (result != null) {
results.add(result)
}
The second example declares an identifier, result, which is now available to the rest of the lexical scope, even though you're done with it in just one line.
The first example, on the other hand, keeps everything self-contained and when you go on reading the rest of the code, you are 100% confident that you don't have to keep in mind the meaning of result.
Kotlin have new features with NullPoint-Exception as Compare to Java.
Basically When we do Coding in Java , then we have to Check with !! in every Flied.
But in Kotlin, it is Easy way to Implement First
as Like,
Suppose, in Kotlin
var response:Json?=Null
response:Json?.let {
this part will handle automatic if response is Not Null....then this Block start Executing }?.run {
This is Nullable But, where we Can put Warring } So, I am Suggest you Guys to Start Work in Kotlin with this Features Provided by Kotlin.
(Flied)?.let { Not Null Value Comes Under }?.run{ Null Value Code }
This will Handle to NullPoint Exception or Protect You App for Crash
What you want to achieve
What you want to achieve is that the Kotlin compiler does a smart cast on the variable you are working with.
In all of your three examples, the compiler can do that.
Example:
if(myVar != null) {
foo(myVar) // smart cast: the compiler knows, that myVar can never be null here
}
The choice
Which one of the options to use, is really a matter of style. What you should not do is mix it up to often. Use one and stick to it.
You don't need to worry about performance since let and run are inlined (see inline function). This means that their code (body) is copied to the call site at compile time so there is no runtime overhead.

When working with Java libraries in Kotlin, is it more idiomatic to use ? or !! on method return values?

I'm new to Kotlin and there's a common pattern that I'm not sure how to deal with most correctly. Take this code, for example, which doesn't compile:
git_repo?.add().addFilepattern()
add() is a call in the JGit library which is purely Java, so its return type is AddCommand!.
I have two options:
git_repo?.add()!!.addFilepattern("test.txt")
and
git_repo?.add()?.addFilepattern("test.txt")
Both work fine and given that
I don't know the intricacies of the library implementation,
the documentation of the JGit library doesn't specify whether add() can return null, and
within this context I'd typically expect add() to not return a null
Which version is more idiomatically correct to write in Kotlin? It seems that this would be a fairly common issue to deal with since basically every non-Kotlin library would introduce this issue.
I would use the ?. safe operator and then put your own exception at the end after an ?: Elvis operator. This way you get a message that is meaningful. Using just !! isn't a very helpful message to someone down the road who has no idea what the intricacies were either.
val cmd = gitRepo.add()?.addFilepattern("test.txt") ?: throw IllegalStateException("assert: gitRepo.add() returned an unexpected null")
cmd.doSomething() // never is null guaranteed
If the value is every null you will have a custom error.
assert: gitRepo.add() returned an unexpected null
And after this line, you will not have to null check because the result of the expression is guaranteed never to be null.
If you inspect the code of the other library and ensure it would never ever be null no matter what, then a !! is appropriate. But if not sure, do one better with the custom message.
Note I dropped the first ?. from your example because I'm assuming git_repo itself is not nullable. Plus I renamed it not to have an underscore which isn't normal Kotlin naming convention.
If you are sure that git_repo will always return a value!! is fine in that case.
It is ugly but !! will always be there when you use Java libraries, and you can't avoid it.
The only reason i would use git_repo?.add()?.addFilepattern("test.txt"), would be if you are returning a value, and you want the value to be nullable so that your calling method can handle the nullable.
fun nullableMethod(): string? {
return git_repo?.add()?.addFilepattern("test.txt")
}
fun callingMethod() {
if(this.nullableMethod() != null) {
}
//Else
}
If you are guaranteed it is never going to null, use !!

Why do optionals in Kotlin require explicit initialisation?

When defining an optional property in a class, Kotlin requires that it is explicitly initialised as null, like so:
var myString: String? = null
Is there any reason that the compiler cannot infer this initial value? I believe Swift would let you skip the = null part, however this is a compiler error in Kotlin. Wouldn't it be simpler to automatically have the value null after writing the following?
var myString: String?
Explicitness is a part of the overall language design in Kotlin. There are no implicit defaults for any types in Kotlin language. There is also desire to discourage (mis)use of nulls, so in respect to initialization nulls are not considered special in any way. If you have a non-nullable string var myString: String they you are required to initialize it with something just like you are required to initialize a nullable string var myString: String? with something, so this way its initial value is always explicit.
Note, technically speaking, String? in Kotlin is not an optional string in Kotlin. In Kotlin it is called a nullable string. However, the most common use-case for nulls is to represent the "absence of value".
There is no reason null must be the initial value of uninitialized variables.
It is not inference.
It is just a rule in Swift, and Kotlin does not have such rule.
Which do you think var a: Int? should be initialized as? 0 or null? Both arguments may have some reasons.
And in Kotlin, nullables are not optionals.