Can't compile a simple Properties loop demo


#1

Hi there,

The following code failed to compile

package test fun main(args : Array<String>) {   for ((name, value) in System.getProperties())           if (name.startsWith("java"))            println("Sys prop: $name=$value") }

I get this error:

ERROR: /Users/zemian/projects/sandbox/kotlin-demo/src/main/kotlin/Test.kt: (4, 12) None of the following functions can be called with the arguments supplied: public final fun jet.String.startsWith(prefix : jet.String) : jet.Boolean defined in kotlin public final fun jet.String.startsWith(prefix : jet.String, toffset : jet.Int) : jet.Boolean defined in kotlin public final fun jet.String.startsWith(ch : jet.Char) : jet.Boolean defined in kotlin

I am using Maven and <kotlin.version>0.4.68</kotlin.version> dependency

Thanks,
Zemian


#2

The diagnostics are unhelpful, sorry about that. The problem is that Properties extends Hashtable<Object,Object>, so your 'name' variable is of type Any, not String. You can cast it or call toString()


#3

Ah, I should have paid attenttion to that. Thanks Andrey.

However another question I have when I try to loop through the stringPropertyNames() set (which is a String set this time), I also get errors.

``

for (name in System.getProperties().stringPropertyNames())
       println(name)

Errors received:

(6, 19) : For-loop range must have an iterator() method

(6, 41) : Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type java.util.Properties?


I think I am missing something silly again. Any hints?

Thanks,
Zemian


#4

Kotlin think that all things came from java are Nullable.

Read this http://confluence.jetbrains.net/display/Kotlin/Null-safety

To fix your problem look here http://blog.jetbrains.com/kotlin/using-external-annotations/

similar quation How do I access String.CASE_INSENSITIVE_ORDER from Kotlin?

Best regards, B7W


#5

Thanks for the links B7W.

Reading it through, and I got it to run like this:

``

for (name in System.getProperties()!!.stringPropertyNames()!!.iterator())
          if (name!!.startsWith(“java.vendor”))
               println(“Sys prop: name={System.getProperty(name)}”)

I understand the intention of Kotlin on avoidance of NPE, but forcing such rule makes using Java integration seems painful and ugly.

I do see that you point to article using “external annotation”, however I don’t see instructions on how to do it without the IDE?