java - 从 Java 访问时,Scala public 变为 private?

标签 java scala maven scala-java-interop

我对 JavaMaven 非常熟悉,但对 Scala 完全不熟悉。我正在尝试从 Java 访问 Scala,但我似乎无法理解的问题之一如下:

我的问题

AccessScala.java 中,我尝试访问 WithinModule.scala 中的变量:

package me.parent.jModule;

public class AccessScala{
    public static void main(String[] args){
        WithinModule within = new WithinModule();
        // -- this is like a static variable
        System.out.println(WithinModule.string);
        // -- this is like an instance variable
        System.out.println(within.string);
        // -- this is a getter, as it should be in Java
        System.out.println(within.getString());
    }
}

这个变量should be public

package me.parent.jModule;

class WithinModule{
  val string : String = "this is the local scala string";
}

但是当运行 mvn clean package 它告诉我这个变量是私有(private)的:

[ERROR] [Error] C:\projectLocation\parent\jModule\src\main\java\me\parent\jModule\AccessScala.java:7: string has private access in me.parent.jModule.WithinModule
[ERROR] [Error] C:\projectLocation\parent\jModule\src\main\java\me\parent\jModule\AccessScala.java:9: string has private access in me.parent.jModule.WithinModule

基本上,我是误解了它应该如何工作,还是我做错了什么?

项目设置

我把项目放在 GitHub 上,并总结了此处可能相关的内容。这些文件是这样组织的

> parent
 | > jModule
 | | > src/main
 | | | > java/me/parent/jModule
 | | | | > AccessScala.java
 | | | > scala/me/parent/jModule
 | | | | > WithinModule.scala
 | | > pom.xml
 | > sModule
 | | > src/scala/me/parent/sModule
 | | | >ExternalModule.scala
 | | > pom.xml
 | > pom.xml

我把我的 parent pom.xml 主要来自 here .经过一些修改,它最终如下所示。这个确切的设置在另一个项目上运行良好,(到目前为止)只有一个案例是 Java 使用用 Scala 编写的类,但两者都有大量代码语言。测试和所有工作正常,直到我们尝试从 Java 中的 Scala 访问 val

我使用 Maven 编译器surefirefailsafe 插件来编译和测试 Java(尚未测试)和 Scala -MavenScalaTest 插件来编译和测试 Scala 代码(还没有测试)。它们被配置为先编译和测试 Scala,然后再转向 Java。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>me</groupId>
    <artifactId>parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>2.13.1</version>
        </dependency>
        <dependency>
            <groupId>org.scalatest</groupId>
            <artifactId>scalatest_2.13</artifactId>
            <version>3.1.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- stuff for compiling and testing Java during `mvn package` -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M3</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>3.0.0-M3</version>
            </plugin>
            <!-- This is for Scala compilation during `mvn package` -->
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>scala-maven-plugin</artifactId>
                <version>4.3.1</version>
                <executions>
                    <execution>
                        <id>scala-compile-first</id>
                        <phase>process-resources</phase>
                        <goals>
                            <goal>add-source</goal>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                    <!--
            <execution>
              <id>scala-test-compile</id>
              <phase>process-test-resources</phase>
              <goals>
                <goal>testCompile</goal>
              </goals>
            </execution>
            -->
                </executions>
            </plugin>
            <plugin>
                <groupId>org.scalatest</groupId>
                <artifactId>scalatest-maven-plugin</artifactId>
                <version>1.0</version>
                <configuration>
                    <reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory>
                    <junitxml>.</junitxml>
                    <filereports>WDF TestSuite.txt</filereports>
                </configuration>
                <executions>
                    <execution>
                        <id>test</id>
                        <phase>process-test-resources</phase>
                        <goals>
                            <goal>test</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <modules>
        <module>jModule</module>
        <module>sModule</module>
    </modules>
</project>

附言

任何正在发生的事情的建议将不胜感激。正如我提到的,我正在尝试让 Java 和 Scala 一起工作,我听说这应该很容易,但我一直遇到问题,这就是其中之一。

最佳答案

分析 scalac -print 输出我们看到了

class WithinModule {
  val string : String = "this is the local scala string"
}

扩展成类似的东西

  class iw$WithinModule extends Object {
    private[this] val string: String = _;
    <stable> <accessor> def string(): String = iw$WithinModule.this.string;
    def <init>(): $line184.iw$WithinModule = {
      iw$WithinModule.super.<init>();
      iw$WithinModule.this.string = "this is the local scala string";
      ()
    }
  }

我们注意到 def string(): String,因此在 AccessScala.java 中尝试

WithinModule within = new WithinModule();
System.out.println(within.string());

关于java - 从 Java 访问时,Scala public 变为 private?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60115151/

相关文章:

java - 异常 org.springframework.beans.factory.CannotLoadBeanClassException : Cannot find class

java - 在Android中实现三角剖分

json - 为蛇形 ADT 配置了 JsonCodec

java - 如何在 Maven 中创建没有 meta-inf 文件夹的 jar?

java - 从另一个 Maven 模块添加 tiles.xml

java - 从 H2 中选择包含空格的列名称

java - 使用字符串调用对象 - Java

scala - 如何合并/组合不同大小的元组列表

scala - Scala新手关于简单数学数组运算的问题

java - maven 构建在某些环境中失败,但随后在同一目录的副本中成功