1

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);
        }
    }
}
Xavien
  • 13
  • 3
  • 1
    1. It has nothing to do with X can't be accessed from Y. The error message clearly states that it has to do with `main` method. 2. It's most likely a problem with Hackerrank itself - for whatever reason it tries to run any public class you define as an entry point, it would need to have `main` in it. – Amongalen Aug 11 '20 at 08:14
  • @Amongalen Well, with my experience on debugging/error messages, a lot of the time when they refer to one area it is actually pointing at another specific area pointed by the area the message refers. Anyhow, I pasted the code onto Eclipse and added public in front of my "Checker class" and there is an error saying that "The public type Checker must be defined in its own file". I did what it told me to and it worked, which I have no idea why I must define it in a separate file? – Xavien Aug 11 '20 at 11:46
  • 1
    You need to declare public classes in their own files. That's one of the requirements put on project structure. That's how it is in Java. – Amongalen Aug 11 '20 at 11:53
  • I'm confused by your question. There is no class declared `public`, and there is no subclassing at all. – daniu Aug 11 '20 at 12:26
  • @daniu I added a comment on the fourth line saying that if I add public in front it results in RE. – Xavien Aug 12 '20 at 11:53
  • @Xavien I read that, but I don't know what regular expressions have to do with any of this. Or if you mean Runtime Exception, please provide the actual type and stack trace that comes with it. – daniu Aug 12 '20 at 11:58
  • @daniu Haha, RE = runtime error. I thought regular expressions' abbreviation was "regex" not "RE". No worries, it seems like others in the comments have cleared my doubts and questions. – Xavien Aug 13 '20 at 11:05

2 Answers2

0

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.

Conffusion
  • 4,335
  • 2
  • 16
  • 28
  • 1
    I don't believe your "once you define" paragraph is true. There is no restriction on where you can define a main method beyond those on where you can place static methods, so there is nothing to say you have to define a main method in the public class if one is present; and since you execute compiled classes, not source files, the JVM runs the class you ask it to, not the public one in a source file. – Andy Turner Aug 11 '20 at 11:33
  • @AndyTurner Sorry, but do you have any sources to counter this? No means of offense, just curious even though your logic should supposedly make sense as that's how Java is defined; however, Conffusion's explanation does provide a possible reason for my problem. – Xavien Aug 11 '20 at 11:40
  • @Conffusion Regarding the link you sent and the comment I replied to from my OP's first comment, I'm assuming out of practice and convention that either you only have one public class with main method in one source file if there are multiple classes, or you need to have multiple public classes each in their own respective source files. – Xavien Aug 11 '20 at 11:51
  • Yes, there can be only one class public and this has to be defined in the source file with the same name. – Conffusion Aug 11 '20 at 12:04
  • @Xavien you would need to consult the language spec to find where it describes the answer's claimed behaviour; this is hard to point to in the spec, because it's not there. You can test to see the behaviour (or lack thereof), but this may indicate an implementation bug with regard to the spec. – Andy Turner Aug 11 '20 at 12:27
  • Thank you for both of your answers, really appreciate it. Cleared my doubts and confusion as a java newbie. – Xavien Aug 12 '20 at 11:57
0

While it's against "customs", it is possible to do what you tried. However the main() method is present in the Solution class, so that's the one you have to run.

From command line you can do that easily:

javac Checker.java
java Solution

as Solution.class will be generated properly.

However if you use an IDE, which you are not very familiar with, you may encounter difficulties when trying to tell them to run a different .class file from the .java they have just compiled. In short: name the file as Solution.java.

tevemadar
  • 12,389
  • 3
  • 21
  • 49