2

I'm learning scala, and to practice, I have started to convert some of my existing java classes into scala, so I can also learn about scala-java inter-op. Following is my project setup:

Scala class :

@Entity
class DemoBeanScala{
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @BeanProperty
    var Id: Long= _

    @BeanProperty
    var str: String= _

    @BeanProperty
    var num: Int = _

    @BeanProperty
    var d:Double = _

    def testFunc(printText: () => Unit){
      printText()
    }

    val pr = () => {
      println("functional programming test")
    }
}

Java class(extract):

@RequestMapping("/demo")
public DemoBeanScala demo(@RequestParam(value="id") Long Id, @RequestParam(value="str") String str, @RequestParam(value="num") int num, @RequestParam(value="d") double d)
{
    DemoBeanScala dbs = new DemoBeanScala();
    dbs.setId(123456);
    dbs.setStr("sample text");
    dbs.setNum(1);
    dbs.setD(2.1);
    dbs.testFunc(dbs.pr);
    return dbs;
}

From what I have learnt, pr in DemoBeanScala class should be accessible in my java class, since no modifier is declared before it. But, after maven compilation(using scala:compile) and running java code, I'm getting an error saying that pr is private in DemoBeanScala class. What am I doing wrong?

2 Answers 2

1

If you look at your compiled class in javap, you will see somethign like this :

public class DemoBeanScala {
  private final scala.Function0<scala.runtime.BoxedUnit> pr;
  public scala.Function0<scala.runtime.BoxedUnit> pr();
  // And some other stuff...
}

You will notice two important difference with Java :

  • Scala respects the uniform access principle, so there is no difference between calling a method without a parameter list or accessing a property. To make that work, the scala compiler will generate a public accessor method and a private field to represent a public property.
  • Java doesn't have methods without a parameter list: they always have at least an empty parameter list.

So, from Java, you need to access the pr property with dbs.pr(), not dbs.pr (or generate a Java-style getter with @BeanProperty, as you did for your other properties, and access it as dbs.getPr()).

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the detailed explanation. using dbs.pr() worked. I'm even more intrigued about java-scala inter-op than I was before :)
1

When you add @BeanProperty that particular property is not visible in java class, only the generated public setters and getters are available or you may access scala like setter (pr_$eq()) and getter (pr()).

I could not find a proper reference, but the following links may helpful for you, they are not directly related to this question, but they will help you understanding.

Scala: Can I declare a public field that will not generate getters and setters when compiled? https://issues.scala-lang.org/browse/SI-4481

1 Comment

Thanks for the explanation, and the reference :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.