3

I have initialized such string Array

var capitals = arrayOf("Tokyo","Moscow","Paris","Washington","Beijing")

But I have not specified its type to String. I thought when I use arrayOf constructor after the elements I should specify type.

enter image description here

Trying code below gives me errors property gettter and setter expected

Why I cannot have the type specified within <> brackets?

var capitals = arrayOf("Tokyo","Moscow","Paris","Washington","Beijing"):Array<String>

3 Answers 3

5

you have to specify type after variable declaration, not after initialization:

var capitals: Array<String> = arrayOf("Tokyo", "Moscow", "Paris", "Washington", "Beijing")

or you can explicitly set type parameter of arrayOf:

var capitals = arrayOf<String>("Tokyo", "Moscow", "Paris", "Washington", "Beijing")
Sign up to request clarification or add additional context in comments.

Comments

2

I thought when I use arrayOf constructor after the elements I should specify type.

The compiler needs to know the type of every value — but it can often infer the type from what it already knows.  So it's common¹ to omit the type.

In this case, the compiler knows that every element is a String, so the list type can only be String (or one of its supertypes: String?, CharSequence, CharSequence?, Comparable<String>, Comparable<String>?, Any, and Any?).  So it infers the most restrictive valid type: List<String>.

Of course, you can manually specify the type if you want to.  (You might want to be able to set nulls or other non-String values in the array later on, for example.)  In fact, in this case there are two ways you could do that.  You could specify the type parameter for arrayOf():

var capitals = arrayOf<Any?>("Tokyo", "Moscow", "Paris", "Washington", "Beijing")

Or you could specify the type of the variable you're assigning it to²:

var capitals: Array<Any?> = arrayOf("Tokyo", "Moscow", "Paris", "Washington", "Beijing")

Both have the same effect here, though the first is probably better.  (It's shorter, which is always good!  Also, it extends to more complex expressions.)


1: There are a few cases where it's good practice to specify the type explicitly, even when you don't need to.  For example:

  • You might want to deliberately loosen the type, as shown above.

  • You might have a value returned from a Java function, where the compiler can't tell whether it should be nullable or not (a platform type).  If you happen to know this, you can specify a nullable or non-nullable type accordingly.

  • You might have a function which is part of your public API, and you don't want to risk its type changing indirectly as a result of some internal changes.  (This is only an issue for functions defined with an expression body, of course; you always have to specify a type for a block body unless it's returning Unit.)


2: That second example shows that the compiler uses the surrounding context when inferring types.  If it looked only at the String parameters when inferring the type parameter for arrayOf(), then that would give an Array<String> — which can't be assigned to an Array<Any?> variable, because Array is not covariant!

But, as the language spec says:

the types of expressions may be derived not only from their arguments, but from their usage as well.

Comments

0

And also you can as Keyword to specific your type by:

var capitals = arrayOf("Tokyo", "Moscow", "Paris", "Washington", "Beijing") as Array<String>

4 Comments

That only works here because you're casting to the same type.  If you cast to a different type, you'll get a runtime error (either an immediate ClassCastException or a later ArrayStoreException).  (Also, there's an extraneous :.)
that is! if you wanna use different types you should try as Array<Any> and this for all kotlin types
No, that won't work properly.  as is a cast, and a cast doesn't convert the value to the required type — it promises the compiler that it already is the correct type.  And in this case, it's not!  Array is not covariant in Kotlin (unlike Java), so Array<Any> and Array<String> are incompatible types.  Either the cast will give a runtime error, or attempts to use the array afterward may do so.
And what i mean in my first comment is as Array<String> and arrayOf<String> can gave you the same results Even they have different Exception Right?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.