Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin: MyClass::class.java vs this.javaClass

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...

enter image description here

enter image description here

enter image description here

(note that the memory address is also different)

Why?

Thanks

like image 325
Matias Elorriaga Avatar asked Mar 03 '17 05:03

Matias Elorriaga


People also ask

What is the difference between :: class and :: class Java in Kotlin?

It is Kotlin Reflection API, that can handle Kotlin features like properties, data classes, etc. By using ::class. java , you get an instance of Class. It is Java Reflection API, that interops with any Java reflection code, but can't work with some Kotlin features.

What is :: class in Kotlin?

:: is just a way to write a lambda expression basically we can use this to refer to a method i.e a member function or property for example class Person (val name: String, val age: Int) Now we can write this to access the person which has the maximium age.


1 Answers

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.

like image 177
Alexander Udalov Avatar answered Sep 20 '22 21:09

Alexander Udalov