带包名的.class文件为何不能在.class文件所在目录运行

大家好,我的问题是这样的,我在G:/javaTest文件下建立的Hello.java,源码如下:

package gdgz.lwj;
public class Hello{
 
 public static void say(){
  System.out.println("hello,java!");
  }
  public static void main(String args[]){
   Hello.say();
   }
 }

当我在G:/javaTest 目录下执行 javac -d . Hello.java文件后,再执行 java gdgz.lwj.Hello 执行成功,但是当我进入G:/javaTest /gdgz/lwj目录(也就是Hello.class文件所在目录) 执行 java Hello时就G:/javaTest 出错了,具体如下

G:\javaTest>java gdgz.lwj.Hello
hello,java!

G:\javaTest>cd gdgz

G:\javaTest\gdgz>cd lwj

G:\javaTest\gdgz\lwj>java Hello
Exception in thread "main" java.lang.NoClassDefFoundError: Hello (wrong name: gdgz/lwj/Hello)
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:621)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:12
4)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
        at java.net.URLClassLoader.access$000(URLClassLoader.java:56)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
Could not find the main class: Hello.  Program will exit.

我们知道如果刚才的Hello.java文件没有带包名,也就是package内容,我们是可以在.class文件所在目录去运行的,我不明白的就是为什么带了包名后了就不能在.class文件所在的目录下去运行,请大家指教。

5个回答

新手最容易犯的错误。

可以在任意目录下执行Java命令。但需要注意:

1、Java命令的参数是“类的完整类名”,而不是“文件名”。
所以,不管在任何目录下运行gdgz.lwj.Hello类,都不能简单写作java Hello,
而需要写成下面形式:

2、如果类路径不在当前目录下,就需要自己设置classpath参数。

例如:
G:\javaTest>java gdgz.lwj.Hello
或者
G:\javaTest\gdgz\lwj>java -cp G:\javaTest gdgz.lwj.Hello
或者
任意目录下>java -cp G:\javaTest gdgz.lwj.Hello

lorewolf311
tianchao_ 原来是加-cp 学习了
7 年多之前 回复
a137705801
a137705801 非常感谢,您的回答应该是最正确的
7 年多之前 回复

应该在G:/javaTest下执行:
java gdgz.lwj.Hello

编译的时候直接指定文件就行了,但是执行的时候肯定是需要带包名的。

yunzhu666
yunzhu666 必须加包名,gdgz.lwj.Hello才是真正的类
7 年多之前 回复
lorewolf311
tianchao_ 我设置了path=%path%;.;G:/javaTest;G:/javaTest/gdgz/lwj/; 在G:/javaTest/gdgz/lwj/下执行java Hello 还是报错
7 年多之前 回复
yunzhu666
yunzhu666 因为对于JVM来说 Hello gdgz.lwj.Hello 是两个完全不同的类。
7 年多之前 回复

这是classpath设置问题 如果你设置为 . 默认就是到当前目录去找类 执行

此时你可以设置classpath为
.;G:/javaTest

jinnianshilongnian
jinnianshilongnian java 包名.类名 必须这么运行 不能少了包
7 年多之前 回复
lorewolf311
tianchao_ 我设置了path=%path%;.;G:/javaTest;G:/javaTest/gdgz/lwj/; 在G:/javaTest/gdgz/lwj/下执行java Hello 还是报错
7 年多之前 回复
jinnianshilongnian
jinnianshilongnian 它找的话 是这样的 必须包名+类名 package gdgz.lwj; public class Hello{ 如果你这样 java Hello 就失去包的意义了
7 年多之前 回复
lorewolf311
tianchao_ 也就是说java [className] 是在当前路径下找Hello.java? 那应该找得到啊
7 年多之前 回复

是不是因为jvm找到的.class文件包名是gdgz/lwj/ 与命令不符。

具体是不是得看看jvm如何执行的了? 高手回答吧

这也许是java操蛋的地方之一

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐