linux / java编译运行“找不到或无法加载主类”

//在主目录下

cd ~

//新建hello.java文件,内容如下:

public class Hello { 
    public static void main(String[] args) { 
        System.out.println("Hello World!"); 
    } 
}

//在~目录下:

javac hello.java

//得到hello.class文件,直接运行报错;

java  hello.class;

//错误:找不到或无法加载主类 hello.class;

//尝试运行

java hello hello.class  ;     //运行正常,正常输出“Hello World!”


//刚入门,不明白其中的道理,请大佬们指教。。。!!!非常感谢!

运行程序不需要写class,注意类名首字母大写的H

java Hello

最后的正常运行,,,说实在的还是有点奇怪。不过这里给一点思路。
1、猜测:java对文件名大小写和类名大小写的匹配检查没有那么严格。(考虑到Windows默认文件系统不区分大小写,而java是跨平台的,这种猜测应当具有一定合理性。如果这个检查过于严格,可能出现程序能够在Windows上运行,却无法在Linux上编译的情形。)
2、你对java指令的理解有一点问题。java指令接受的参数是类名不是文件名。
3、当你不显式指定时,java不知道你的类名到底是以哪个类文件为根的(它不会自动去当前目录下寻找,因为相当多的情况下主类确实不在工作目录,尤其是对大型项目而言。我猜测这种设计是为了防止新人误操作),自然不能够正确执行。我个人喜欢通过-classpath选项来明确指定类的目录,这样java才会在指定目录下查找主类。我猜测直接指定主类的文件名也有类似的效果,就像你所做的这样。
4、再次强调,java指令接受的主类信息是类名而不是文件名,只指定文件名肯定无论如何都是不行的。我猜测这和java的包结构设计有关:hello.class也可以理解为一个叫做hello的包下的一个名为class的类,你直接指定文件名的话,java会误以为这是一个类名,但这个类实际上并不存在。(提示:考虑你的import指令格式。事实上,如果你不import,也可以通过完整包名加类名来指定一个具体的类。那些可以直接用的类也是有包的,比如String的完整类名是java.lang.String。因此,事实上类名和文件名是不可能自动区分的,java指令只能通过你传递参数的位置进行区分。这种情况下,如果你只给出一个参数,java将不得不认为它是一个类名。你可能会疑惑为什么java找不到类时为何不去自动找文件,答案非常简单:如果设计这种具有二义性的参数,将会带来灾难性的后果:如果当前目录下既有hello.class文件,又有hello.class这个类,那么其中将会有一个无论通过何种方法都无法访问,而这是我们不希望出现的状况。因此,指令设计一定会避免具有多种不同含义的选项。)
最后还是建议:文件名和类名的大小写最好严格保持一致,这是良好的编程习惯(java的习惯跟c/c++都不太一样)。如果不遵守,可能会给他人乃至自己带来维护上的麻烦。

注意大小写。文件名是hello,主类名也得是hello,不能是Hello

文件名要和类名保持一致,你把文件名改成大写的试试 Hello.java,再重新编译运行