Kotlin: data class private setter public getter - kotlin

Is there any way I can make a private setter and a public getter in a Kotlin Data Class?
data class Test(var attribute: String) {
// attribute can be mutated inside this class
// but outside only readable ?
}

A simple approach would be to have a private var, but then to provide a public property that delegates to it:
data class Test (private var attribute_ : String) {
val attribute: String get() = attribute_
}

To add some background to the other answer:
There's no way to do this directly in the constructor, though there have been several proposals as to how it could be added to the language; see here.
If it weren't a data class, I'd suggest this alternative:
class Test(_attribute: String) {
var attribute = _attribute
private set
}
That only stores one value in the object, so is marginally more efficient.
But since this is a data class, that's not possible.  (Data classes can't have non-properties in their primary constructors.)  So the other answer's suggestion seems best.

Related

How to get private fields and call private methods in Advice wrapped method?

Redefine method:
private <T> void redefine(Class<T> type, UnaryOperator<DynamicType.Builder<T>> operation) {
DynamicType.Builder<T> builder = new ByteBuddy().redefine(type);
ClassLoader systemClassLoader = Entity.class.getClassLoader();
operation
.apply(builder)
.make()
.load(systemClassLoader, ClassReloadingStrategy.fromInstalledAgent());
}
Use of Advice:
redefine(ChunkGeneratorAbstract.class, builder -> builder
.method(named("buildNoise")
.and(takesArguments(3)))
.intercept(Advice.to(ChunkGeneratorAdvice.class).wrap(StubMethod.INSTANCE)));
ChunkGeneratorAdvice:
#Advice.OnMethodExit
public static void buildNoise(GeneratorAccess generatoraccess, StructureManager structuremanager, IChunkAccess ichunkaccess,
#Advice.This ChunkGeneratorAbstract chunkGenerator) {
int val = chunkGenerator.n;
Object someVal = chunkGenerator.privateMethod();
}
chunkGenerator.n is a private field. How to get its value?
Also, how i can call private methods like chunkGenerator.privateMethod()?
For a private field, you can use Advice.FieldValue as an annotation on a parameter to read and write from it. For a method call, you would need to use a MemberSubstitution. You would then declare an empty method in the advice class that has the same signature and call this method from your advice code. Later, you would use MemberSubstitution to switch the method calls.

Kotlin object, an implementation vs instance

In Objects in Kotlin: Create safe singletons in one line of code (KAD 27) Antonio Leiva states:
In fact, an object is just a data type with a single implementation.
I would expect to see the term instance rather than implementation used here. Is there some nuance that I am missing?
Sure it does have a single instance after all, but I believe what they meant to say is that whatever you write in an object is final and you can not override it. Even if you make it open(for argument purpose), you can not make an anonymous object out of it since the anonymous class can't be used on a SingleTon instance.
So " data type with a single implementation" means, whatever you write is the final implementation. An instance is, after all, a result of some implementation.
For reference, I am adding a decompiled code of object declaration.
public final class Test {
#NotNull
private static final String testMember = "Test";
public static final Test INSTANCE;
#NotNull
public final String getTestMember() {
return testMember;
}
private Test() {
}
static {
Test var0 = new Test();
INSTANCE = var0;
testMember = "Test";
}
}

Typescript Abstract Class Method Access Derived Class Property

abstract class MyClass() {
protected static foo: Array<number>;
protected static doWorkOnFoo(): void {
let x: number = 0;
for (let f of | what goes here? this? self?|.foo) {
x = x + foo;
}
}
}
When implementing an abstract class, and wanting derived classes to have a static property and a static method that operates on those properties, how would one access those in the abstract class so that the derived class can just use that method?
I know this can be worked around by just setting a default value on the static property and using this, but this sparked my interested and I'm curious to know if there's some way to access generic derived class or something from an abstract class in TS.
Thanks in advance!
EDIT:
While I wasn't able to find exactly what I was looking for (see comments), a workable solution is to change the signature of the doWorkOnFoo() method to the following:
protected static doWorkOnFoo(): (typeof MyClass) => void;
Since it is already an abstract class it can take a derived class as an argument and then reference the derived class's static properties.

Is the default constructor really necessary for nhibernate to persist an object?

for some reason I don't wanna let user to create an instance of the object, without sending a property to the constructor
but as I know the object should have default constructor and so it would be possible to create an instance with out sending requierd property.
is there any way to prevent this problem? and if yes does it have any side effect?
Just use a protected default constructor:
public class Product
{
protected Product() { }
public Product(Category category)
{
this.Category = category;
}
}
"NHibernate allows a private default constructor for Value Objects, but for Entities you will need a default public or protected constructor as private is not sufficient."
Here you can find something:
https://github.com/davybrion/companysite-dotnet/blob/master/content/blog/2009-10-why-nhibernate-entities-need-a-public-or-protected-parameterless-constructor.md
Here there's an experiment to work without constructor:
http://kozmic.net/2011/03/20/working-with-nhibernate-without-default-constructors/
This is an example working with Dependency Injection:
http://nhibernate.info/blog/2008/12/12/entities-behavior-injection.html

Ensuring only factory can create instance

class XFactory {
private XFactory() {}
static void getX() {
if(...)
return new A(new XFactory());
else
return new B(new XFactory());
}
}
class A {
private A() {}
public A(XFactory xf) {}
}
class B {
private B() {}
public A(XFactory xf) {}
}
By this way I can ensure only Factory can create instances of it's belonging Classes.
Is this right approach or there is any other alternative/good approach?
The common approach (in C++) is to make the "belonging classes" constructors private, and have them declare the factory class as friend.
I would make classes A and B friends of XFactory, and keep all their constructors private. Therefore, only XFactory has access to their constructors.
That is, in C++. In Java or C#, I don't see any clean way of enforcing that at compile-time. Your example is far from fool-proof and even a bit confusing, since as long as one has an instance of XFactory, he can pass it to the constructor of A or B and instantiate them directly like that.
If you were up for hacks and could not make your constructors private, you could:
Make your factory a global singleton and to create an object:
Create a random key
Add that key to a private list in the factory object of keys in use
Pass the key to the constructor
Have the constructor retrieve the global factory object and call it to validate the key.
If they key validation fails, scuttle your program (call exit, die, ... whatever is appropriate). Or possibly email a stack tract to an admin. This is the kind of thing that should be caught quickly.
(Do I get hack points?)
Jacob
In Java you can make the constructors private and provide the factory in the form of a public nested class, since nested classes have access to the private members of the class in which they are declared.
public class ExampleClass {
private ExampleClass() {
}
public class NestedFactory {
public ExampleClass createExample() {
return new ExampleClass();
}
}
Anyone who wanted to could create an instance of ExampleClass.NestedFactory and through it instantiate ExampleClasses.
I haven't been able to figure out a way to do this that lets you then inherit from ExampleClass since the Java compiler demands that you specify a constructor for the superclass... so that's a disadvantage.