【问题标题】:A class with no modifier (default) cannot access a subclass declared as public? Java没有修饰符(默认)的类不能访问声明为公共的子类?爪哇
【发布时间】:2020-11-30 20:54:15
【问题描述】:

我只是在 Hackerrank 上练习,因为我对 Java 还是很陌生(我只熟悉 C 和 C++,使用最少的 Python/Matlab/C#)。基本上我们只需要从头开始编写下面的“Checker 类”。但是,我注意到当我将 public 添加到 Checker 类时,它会导致运行时错误。有谁知道为什么?我在网上找不到任何答案。

另外,是的,我知道访问修饰符限制了他们可以访问类范围的程度,但默认类如何无法访问公共类的方法对我来说没有意义。我假设可能是我正在实现导致问题的父类?这是我在 Hackerrank 上收到的 RE 消息:

Error: Main method not found in class Checker, please define the main method as:
   public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application

如果有兴趣,链接练习题供参考:https://www.hackerrank.com/challenges/java-comparator/problem

import java.util.*;

// Write your Checker class here
class Checker implements Comparator<Player>{  //If I add "public" in front I get RE
    @Override
    public int compare(Player A, Player B){
        if(A.score == B.score)
            return A.name.compareTo(B.name);
        else
            return B.score - A.score;
        // return A.compareTo(B);
    }
    
}

class Player{
    String name;
    int score;
    
    Player(String name, int score){
        this.name = name;
        this.score = score;
    }
}

class Solution {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();

        Player[] player = new Player[n];
        Checker checker = new Checker();
        
        for(int i = 0; i < n; i++){
            player[i] = new Player(scan.next(), scan.nextInt());
        }
        scan.close();

        Arrays.sort(player, checker);
        for(int i = 0; i < player.length; i++){
            System.out.printf("%s %s\n", player[i].name, player[i].score);
        }
    }
}

【问题讨论】:

  • 1.它与 X 无关,无法从 Y 访问。错误消息明确指出它与 main 方法有关。 2. 这很可能是 Hackerrank 本身的问题 - 无论出于何种原因它试图运行您定义为入口点的任何公共类,它都需要在其中包含 main
  • @Amongalen 好吧,根据我在调试/错误消息方面的经验,很多时候当它们指代一个区域时,它实际上是指向消息所指区域所指向的另一个特定区域。无论如何,我将代码粘贴到 Eclipse 上并在我的“Checker 类”前面添加了 public,并且有一个错误说“必须在自己的文件中定义公共类型 Checker”。我做了它告诉我的事情,它工作了,我不知道为什么我必须在一个单独的文件中定义它?
  • 您需要在自己的文件中声明公共类。这是对项目结构提出的要求之一。在 Java 中就是这样。
  • 我对你的问题感到困惑。没有声明类public,也没有子类化。
  • @daniu 我在第四行添加了一条评论,说如果我在前面添加 public 它会导致 RE。

标签: java class public implements


【解决方案1】:

有趣的问题,但我在整个职业生涯中从未使用过这个。

如果源文件中没有公共类,那么main方法可以 位于任何类中,我们可以为源文件指定任何名称。

来源:https://dzone.com/articles/why-single-java-source-file-can-not-have-more-than

由于@Andy Turner 的评论,我对其进行了进一步测试,实际上您可以在其他类(公共类除外)中使用 main 方法。这完全取决于您如何称呼它:

package sample;

class Problem  {
    public static void main(String[] args) {
        System.out.println("main of Problem");
    }

}

public class Solution {
    public static void main(String[] args) {
        System.out.println("main of Solution");
    }
}

源文件名必须是 Solution.java,因为这是公共类,但您可以调用两个主要方法:

  > java sample.Solution  
  main of Solution
 
  > java sample.Problem
  main of Problem

当您从解决方案中删除主方法时,您仍然可以调用 sample.Problem。

【讨论】:

  • 我不相信您的“一旦定义”段落是正确的。除了可以放置静态方法的位置之外,在哪里可以定义主方法没有任何限制,所以没有什么可以说你必须在公共类中定义一个主方法,如果存在的话;并且由于您执行的是已编译的类,而不是源文件,因此 JVM 会运行您要求它执行的类,而不是源文件中的公共类。
  • @AndyTurner 抱歉,您有什么资料可以反驳吗?没有冒犯的意思,只是好奇,即使你的逻辑应该是有意义的,因为这就是 Java 的定义方式;但是,Conffusion 的解释确实为我的问题提供了一个可能的原因。
  • @Conffusion 关于您发送的链接和我从我的 OP 的第一条评论中回复的评论,我假设出于实践和惯例,要么您在一个来源中只有一个带有 main 方法的公共类文件,如果有多个类,或者您需要在各自的源文件中有多个公共类。
  • 是的,公共类只能有一个,并且必须在源文件中定义同名。
  • @Xavien 您需要查阅语言规范以找到它描述答案声称的行为的位置;这在规范中很难指出,因为它不存在。您可以测试以查看行为(或缺乏行为),但这可能表明与规范有关的实现错误。
【解决方案2】:

虽然它违反“习俗”,但可以做你尝试过的事情。但是 main() 方法存在于 Solution 类中,所以这是您必须运行的方法。

从命令行你可以很容易地做到这一点:

javac Checker.java
java Solution

Solution.class 会正确生成。

但是,如果您使用您不太熟悉的 IDE,当您试图告诉他们运行与他们刚刚编译的 .java 不同的 .class 文件时,您可能会遇到困难。简而言之:将文件命名为Solution.java

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-04
    • 1970-01-01
    • 2017-02-19
    • 1970-01-01
    • 2011-10-09
    • 2016-10-11
    • 2015-12-02
    • 2011-01-31
    相关资源
    最近更新 更多