I'm migrating a project to Kotlin, and this:
public static Properties provideProperties(String propertiesFileName) {
Properties properties = new Properties();
InputStream inputStream = null;
try {
inputStream = ObjectFactory.class.getClassLoader().getResourceAsStream(propertiesFileName);
properties.load(inputStream);
return properties;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
is now:
fun provideProperties(propertiesFileName: String): Properties? {
return Properties().apply {
ObjectFactory::class.java.classLoader.getResourceAsStream(propertiesFileName).use { stream ->
load(stream)
}
}
}
very nice, Kotlin! :P
The question is: this method looks for a .properties
file inside src/main/resources
. Using:
ObjectFactory::class.java.classLoader...
it works, but using:
this.javaClass.classLoader...
classLoader
is null
...
(note that the memory address is also different)
Why?
Thanks
If you invoke javaClass
inside a lambda passed to apply
, it's called on the implicit receiver of that lambda. Since apply
turns its own receiver (Properties()
in this case) into the implicit receiver of the lambda, you're effectively getting the Java class of the Properties
object you've created. This is of course different from the Java class of ObjectFactory
you're getting with ObjectFactory::class.java
.
For a very thorough explanation of how implicit receivers work in Kotlin, you can read this spec document.