Reputation: 97
I'm trying to write factory class in Kotlin. In Java:
public class MyFactory {
private static MyFactory instance = null;
private Properties props = null;
private FirstClass firstInstance = null;
private SecondClass secondInstance = null;
private MyFactory() {
props = new Properties();
try {
props.load(new FileInputStream("path/to/config"));
String firstClass = props.getProperty(“first.class”);
String secondClass = props.getProperty(“second.class”);
firstInstance = (FirstClass) Class.forName(firstClass).newInstance();
secondInstance = (SecondClass) Class.forName(secondClass).newInstance();
} catch (Exception ex) {
ex.printStackTrace();
}
}
static {
instance = new MyFactory();
}
public static MyFactory getInstance() {
return instance;
}
public FirstClass getFirstClass() {
return firstInstance;
}
public SecondClass getSecondClass() {
return secondInstance;
}
}
And I encountered few issues trying to rewrite this in Kotlin. I tried to generate code first with Java converter on try.kotlinlang.org. The result is:
class MyFactory private constructor() {
private var props: Properties? = null
private var firstInstance: FirstClass? = null
private var secondInstance: SecondClass? = null
init {
try {
props!!.load(FileInputStream("path/to/conf"))
val firstClass = props!!.getProperty("prop")
val secondClass = props!!.getProperty("prop")
firstInstance = Class.forName(firstClass).newInstance() as FirstClass
secondInstance = Class.forName(secondClass).newInstance() as SecondClass
} catch (ex: Exception) {
ex.printStackTrace()
}
}
companion object {
var instance: MyFactory? = null
init{
instance = MyFactory()
}
}
}
I am using IntelliJ IDEA 15, and it says that this class don't have getInstance()
method, but when I try to implement it it says:
Platform declaration clash: The following declarations have the same JVM signature:
fun <get-instance>(): my.package.MyFactory?
fun getInstance(): my.package.MyFactory?
As I remember, getters are auto-implemented only in data classes.
Can someone clarify this situation or maybe tell me the right way how to implement this?
UPDATE:
I make use of this class in Kotlin by refering to properties itself, ex. MyFactory.instance!!.firstInstance, but it feels wrong to do it this way.
Upvotes: 2
Views: 646
Reputation: 148089
The explanation is the following:
Kotlin compiler creates getters and setters for all properties, but they are visible only in Java. In Kotlin, properties are idiomatic, and they are even generated from Java getter and setter pair when you use Java classes.
Thus declaring a method getInstance
indeed clashes with the auto-generated getter that will be visible in Java code.
If you need custom getter behaviour please use getter syntax:
var instance: MyFactory? = null
get() {
/* do something */
return field
}
In this example field
is a soft keyword and means backing field for the property.
It is documented here.
By the way, object declaration seems to fit your case well.
Upvotes: 3