Search code examples
javaclasspublicimplements

A class with no modifier (default) cannot access a subclass declared as public? Java


I was just doing practice on Hackerrank since I'm still pretty new to Java (I'm only experienced with C and C++, with minimal Python/Matlab/C#). Basically we only had to write the "Checker class" below from scratch. However, I noticed that when I add public to the Checker class it results in runtime error. Does anyone know why? I couldn't find any answers on this online.

Also, yes, I know access modifiers restrictions on how much they can have access to the scope of classes, but it does not make sense to me on how a default class cannot access a public class's method. I'm assuming it is perhaps I'm implementing a parent class that's causing the problem? Here is the RE message I receive on Hackerrank:

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

If interested, link to the practice problem for reference: 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);
        }
    }
}

Solution

  • Interesting question but I've never used this in my whole career.

    If there is no public class in the source file then main method can lie in any class and we can give any name to the source file.

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

    Because of the remark of @Andy Turner, I tested it a little bit further and indeed you can have a main method in other classes (other than the public one). It all depends on how you call it:

    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");
        }
    }
    

    The source file name must be Solution.java as this is the public class but you can call both main methods:

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

    You can still call sample.Problem when you remove the main method from Solution.