scala类中的公共类成员在java类中不可访问

时间:2016-05-03 07:16:58

标签: java scala

我正在学习scala,为了练习,我已经开始将一些现有的java类转换为scala,所以我也可以学习scala-java inter-op。以下是我的项目设置:

Scala类

@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类(摘录):

@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;
}

据我所知, DemoBeanScala 类中的 pr 应该可以在我的java类中访问,因为之前没有声明修饰符。但是,在maven编译(使用 scala:compile )并运行java代码之后,我收到一条错误,说pr在DemoBeanScala类中是私有的。我做错了什么?

2 个答案:

答案 0 :(得分:0)

如果你看一下javap中的编译类,你会看到这样的一些东西:

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

您会注意到Java的两个重要区别:

  • Scala尊重uniform access principle,因此调用没有参数列表的方法或访问属性没有区别。为了实现这一目的,scala编译器将生成一个公共访问器方法和一个私有字段来表示公共属性。
  • Java没有没有参数列表的方法:它们总是至少有一个空参数列表。

因此,从Java开始,您需要使用pr访问dbs.pr()属性,而不是dbs.pr(或使用@BeanProperty生成Java样式的getter,就像您所做的那样对于您的其他媒体资源,并将其作为dbs.getPr())进行访问。

答案 1 :(得分:0)

当您添加@BeanProperty特定属性在java类中不可见时,只有生成的公共setter和getter可用,或者您可以访问scala,如setter(pr_$eq())和getter({{1 }})。

我找不到合适的参考资料,但以下链接可能对您有所帮助,它们与此问题没有直接关系,但它们会帮助您理解。

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