Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BeanProperty no longer allowed on private fields. #4481

Closed
scabug opened this issue Apr 13, 2011 · 6 comments
Closed

BeanProperty no longer allowed on private fields. #4481

scabug opened this issue Apr 13, 2011 · 6 comments

Comments

@scabug
Copy link

scabug commented Apr 13, 2011

=== What steps will reproduce the problem (please be specific and use wikiformatting)? ===
In scala 2.7.7, @BeanProperty was allowed on private fields. In 2.8.1, this is no longer allowed.

@scala.reflect.BeanProperty private var test: Int = _

=== What is the expected behavior? ===

Allow @BeanProperty on private fields.

One reason to use getters and setters is to hide implementation details. The field should be allowed to be private, otherwise it can "leak out" and be accessed directly, and become part of the ABI of the class.

=== What do you see instead? ===

<console>:5: error: `BeanProperty' annotation can only be applied to non-private fields

=== What versions of the following are you using? ===

  • Scala: 2.8.1
  • Java: 1.6.0_22
  • Operating system: linux
@scabug
Copy link
Author

scabug commented Apr 13, 2011

Imported From: https://issues.scala-lang.org/browse/SI-4481?orig=1
Reporter: J Robert Ray (jrray)

@scabug
Copy link
Author

scabug commented Apr 14, 2011

@lrytz said:
When you annotate a public field with @BeanProperty, the getter and setter will be public, but the actual field is private. This is what you want.

@scabug
Copy link
Author

scabug commented Apr 14, 2011

J Robert Ray (jrray) said:
I understand that the field is private, and that the 'setTest' and 'getTest' generated methods are public. However, the 'test' and 'test_=' methods are also public. Now there are two public ways to assign to test, setTest and test_=.

If I wish to later remove the test field without breaking ABI, I need to create dummy methods for both pairs of methods.
If I wish to later replace the generated setTest with a custom setTest that has a side effect, I must also replace test_= to also perform the side effect.

The compiler allows private vars. Why does the compiler disallow private vars when @BeanProperty is also desired?

@scabug
Copy link
Author

scabug commented Apr 14, 2011

@lrytz said:
@BeanProperty is a Java-compatibility tool, it helps you integrating your Scala code with certain Java frameworks. The generated set* and get* methods are just aliases for the Scala getter and setter, and they will have the same visibility.

If you want custom getters or setters, you have to write them manually. It's true that this then does not integrate nicely with @BeanProperty, this problem has been identified before (https://groups.google.com/forum/#!searchin/scala-user/beanproperty/scala-user/CQv2OXttTm8/OvFKJ4-Mf4EJ).

see also #2215.

@scabug
Copy link
Author

scabug commented Apr 14, 2011

J Robert Ray (jrray) said:
Thank you for your comments. I feel your scala-user thread reinforces my position. I am not asking to be able to customize the accessors; I was giving examples of why it is important to allow private vars.

My observation in scala 2.8.1 is that the scala accessors take on the visibility of the var, but the Bean accessors are always public.

Using scala -print, if I make my var protected, I see:

    @scala.reflect.BeanProperty private[this] var test: Int = _;
    protected <accessor> def test(): Int = line5$$object$$$$iw$$$$iw.this.test;
    protected <accessor> def test_=(x$$1: Int): Unit = line5$$object$$$$iw$$$$iw.this.test = x$$1;
    def setTest(x$$1: Int): Unit = line5$$object$$$$iw$$$$iw.this.test = x$$1;
    def getTest(): Int = line5$$object$$$$iw$$$$iw.this.test();

getTest and setTest are public (as they should be IMO).

I really just want to know why private is disallowed. I found your comment in the compiler source, "avoids name clashes with private fields in traits." That's unsatisfying. I promise to not name a private field "setTest" in any trait I inherit from!

@scabug
Copy link
Author

scabug commented Apr 15, 2011

@lrytz said:
Replying to [comment:4 jrray]:

Thank you for your comments. I feel your scala-user thread reinforces my position. I am not asking to be able to customize the accessors; I was giving examples of why it is important to allow private vars.

My observation in scala 2.8.1 is that the scala accessors take on the visibility of the var, but the Bean accessors are always public.

Yes, the problem with this solution is that it's wrong. When you have two traits with two private variables of the same name, and both have @BeanProperty, and then you mix them into one class, you get a conflict.

@scabug scabug closed this as completed May 18, 2011
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant