Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: Can I declare a public field that will not generate getters and setters when compiled?

Tags:

scala

In Scala when you declare a val or a var, Scala will automatically generate a private field and the getters and setters for you when compiled to bytecode.

E.g.

class myClass {
    val name = "My Name"
}

will compile to create the equivalent

class myClass {
    private string name;
    public string name();
    public void name_$eq(string);
}

Where name() and name_$eq are the getters and setters for the private string name.

I know you can force it to not provide the getters and setters for private fields by declaring them as private[this] val/var blah, but I need to be able to create a public field that doesn't generate getters and setters when compiled.

Is this even possible in Scala?

Thanks

like image 926
guoguojin Avatar asked Apr 27 '12 08:04

guoguojin


People also ask

Are getters and setters always public?

In general, they should be public. If they are private they can only be called from within your class and, since you already have access to the private variables within your class, are redundant. The point of them is to allow access to these variables to other, outside, objects.

Which action will automatically create a getter and setter for a class in Scala?

When you define a class field as a var , Scala automatically generates getter and setter methods for the field, and defining a field as a val automatically generates a getter method, but you don't want either a getter or setter.

Can getter setter be private?

The private getter/setter methods provide a place for adding extra behavior or error checking code. They can provide a place for logging state changes or access to the fields. They can provide a place for adding your debug code while testing.


2 Answers

The generated class does not contain getters or setters as can be seen in the sample you provided. The generated classes does not contain java bean getters or setters. To actually make the compiler generate getX and setX methods for a var you need to annotate that variable with @BeanProperty.

If you would like to have a public field accessible from java I think you are out of luck unfortunately. Atleast, I have not seen a way to accomplish that only using scala.

You could accomplish it by mixing scala and java. With a java class like:

public abstract class JavaClassWithPublicField {
   public String name = "My name";
}

And then in your scala code inherit that class:

class ScalaClassWithPubilcField extends JavaClassWithPublicField

That's likely the cleanest way to do it.

like image 57
Emil H Avatar answered Oct 19 '22 11:10

Emil H


Presumably you want to force the way your attribute is represented because you're accessing from Java. (If you're trying to "optimise" your byte code by getting rid of the getter then you're wasting your time, the VM will quickly inline them.) Unfortunately for you, to keep the door as wide open as possible for future improvements, the Scala specs don't specify how Scala code should be translated to byte code. This means that even if you find a trick that works for a given version of Scala, it's not guaranteed to work in subsequent versions.

The recommended approach in these cases is to write the Java-visible code in Java and then have a small glue class written in Scala - something like the answer given by @Emil is great.

like image 26
rxg Avatar answered Oct 19 '22 11:10

rxg