If I have something like the following:
interface IRecordService {
fun doSomething () : Record
}
@MongoRepository
interface IRecordRepository : MongoRepository<Record, String> {
}
@Service
class RecordService (
private val recordRepository : IRecordRepository // or just val instead of private val
) : IRecordService
{
override fun doSomething () : Record {
// does something
}
}
Is there any difference between using private val
in the RecordService
constructor vs just val
? I've seen both being used but couldn't tell if there was a recommended way or why.
CodePudding user response:
If you put val
, it will be a constructor parameter and property. If you don't, it will be a constructor parameter (NOT property).
See Why to put val or var in kotlin class constructors
CodePudding user response:
This isn't specific to Spring or Mongo; it's just core Kotlin. There are several things going on here; I'll try to unpick them.
Consider the simpler definition:
class MyClass(i: Int)
The parens specify the primary constructor: any parameters there (such as i
) are passed into the class, and are available during construction. So you could pass them up to the superclass constructor, use them in property initialisers, and/or in an init
block:
class MyClass(i: Int) : MySuperclass(i) {
val someProperty = i
init {
println("i is $i")
}
}
However, they don't persist after the instance has been constructed — so you couldn't refer to them in methods, or from outside the class.
If you want to do that, you have to define a property for each parameter you want to persist. You could do that explicitly, e.g.:
class MyClass(i: Int) {
val i2 = i
}
Here every instance of MyClass
has a property called i2
which is initialised to the i
constructor parameter.
However, because this is a common pattern, Kotlin provides a shortcut. If you specify val
or var
in the primary constructor:
class MyClass(val i: Int)
then Kotlin creates a property with the same name as the parameter, and initialises it for you. So every instance of the above class has a property called i
that you can refer to at any time.
By default, properties in Kotlin are public
: you can access them from inside the class, from subclasses, from other classes in the same module, and from any other code that has a MyClass
instance.
However, in some cases it's useful to restrict access, so you can add a visibility modifier: internal
prevents code in other modules from seeing it, protected
allows only subclasses to see it, and private
makes it visible only inside the class itself.
So, to answer your question: without the private
modifier, any code that had access to your RecordService
would be able to access its recordRepository
property; adding private
prevents that, and means that only code within RecordService
can see it.
In general, it might be a good idea to centralise all access to the recordRepository
in the one class; then making it private
would ensure that no other code can muck around with it. That would make it easier to see what's going on, easier to debug, and safer to work on. (However, we obviously don't know about the rest of your program, and can't advise on whether that would be a good plan in your case.)
By the way, using an I
prefix for interfaces is not a convention that's used much in Kotlin (or Java). There's often little point in having an interface with only one implementation; and if you could have multiple implementations, then better to use a simple term for the interface and then more specific terms for the implementations. (For example: the List
interface with ArrayList
and LinkedList
classes, or Number
with Int
and Long
.)
CodePudding user response:
Firstly if you use val
it converts this constructor parameter to property,If you do not want to hide this property (to set it) from other classes,you can use val
.But if you do not want your property to be changed by other classes you should use private val
instead.
CodePudding user response:
Well, you can use both val
and private val
in your constructor there's no problem in that, it's just that with private
keyword your properties wont be modified or accessed by some other class, so it basically provides some data hiding. If you talking about difference in functionality inside your RecordService
class, then no there wont be any difference.