黑马程序员技术交流社区

标题: 关于java文件名和类名的小问题 [打印本页]

作者: 赵崇友    时间: 2013-3-29 16:16
标题: 关于java文件名和类名的小问题
本帖最后由 赵崇友 于 2013-3-30 16:52 编辑

1,希望大家看完后,看清楚问题再回答。谢谢

如下图:
public  class  Test1//定义类名
{
public static void main(String[] args) //程序的入口(主方法)
{
System.out.println("Hello Java!");//打印Hello Java!语句
}
}
保存到DTest目录下,名为Test.java
编译出现下图的情况。
编译提示:Test.java:14: Test1 是公共的,应在名为 Test1.java 的文件中声明
public class  Test1//定义类名
       ^
1 错误
上述描述是什么意思啊?
我知道将文件名改为Test1.java后能编译成功。
或将类的修饰符public去掉也能通过编译,然后运行 java Test1也能得到结果。
但是这个情况的根本原因是什么啊?(想知道原理)
期待高手的解答。

图片1.png (118.35 KB, 下载次数: 46)

图片1.png

作者: kelline    时间: 2013-3-29 16:27
public  class  Test1//定义类名
{
public static void main(String[] args) //程序的入口(主方法)
{
System.out.println("Hello Java!");//打印Hello Java!语句
}
}
保存到D盘Test目录下,名为Test.java。
作者: kelline    时间: 2013-3-29 16:28
你保存的文件名是Test.java  而你在程序里面public class  后却是 Test1
作者: 赵崇友    时间: 2013-3-29 16:30
kelline 发表于 2013-3-29 16:28
你保存的文件名是Test.java  而你在程序里面public class  后却是 Test1

我知道,具体原因求解释
作者: 胡志超    时间: 2013-3-29 16:31
你去掉class前的public  就可以了
作者: 赵崇友    时间: 2013-3-29 16:34
胡志超 发表于 2013-3-29 16:31
你去掉class前的public  就可以了

嗯嗯,求解释具体的原因。
作者: 胡志超    时间: 2013-3-29 16:37
赵崇友 发表于 2013-3-29 16:34
嗯嗯,求解释具体的原因。

class前加public,那么.java名和类名必须保持一致,如果不加public那么就不用了
作者: kelline    时间: 2013-3-29 16:38
如果你家public , 你的类名和文件名必须一样, 不加public 你的类名和保存的文件名可以不一样
作者: 赵崇友    时间: 2013-3-29 16:39
胡志超 发表于 2013-3-29 16:37
class前加public,那么.java名和类名必须保持一致,如果不加public那么就不用了 ...

嗯嗯,这个我知道,我就是想知道 为什么加上public必须保持一致,而不加可以不用呢?
作者: kelline    时间: 2013-3-29 16:40
那是java的命名规则, 再具体的就不知道了
作者: 赵崇友    时间: 2013-3-29 16:42
kelline 发表于 2013-3-29 16:38
如果你家public , 你的类名和文件名必须一样, 不加public 你的类名和保存的文件名可以不一样  ...

这是语法问题,能解决掉,我是想了解加了public为什么要一致!其中的原理
作者: 赵崇友    时间: 2013-3-29 16:43
kelline 发表于 2013-3-29 16:40
那是java的命名规则, 再具体的就不知道了

嗯嗯,等大神的到来吧!!
作者: 小黑黑    时间: 2013-3-29 19:56
我不是大神,查了一点资料,以下是个人愚见,希望有帮助:
首先说明结论:一个编译单元(个人理解为执行main函数所调用到的所有文件)中只能有一个public类,且这个类的文件名必须要和其类名相同,包括大小写也必须一样。
1、一个编译单元只能有一个public类的原因:
第一、public的意思是所有类都能访问,包括包以外的类。public是作为这个编译单元的公开接口存在的。
第二、java程序的入口是main方法,所以被定为public的这个类一定是main方法的类,且这个类的名称要和文件名一直,因为虚拟机是要开始找main方法这个入口的。
第三、你可以根据需要,添加任意辅助功能的public权限的类,但是如果这个编译单元(注意是编译单元)里面有两个或以上public类的话,那么编译器就会报错。
建议:
第一、不要在一个源文件中写多个类。在标准的java代码编写时,无论代码量是多少,最好一个源文件只有一个类或接口(即使是接口也要如此),因为java是面向对象的语言,每个类都是抽象的结果,所以每个类要单独写在一个源文件里。
第二、只要要有一个是public类,虽然可以在编译单元中没有public类,即没有公开的接口,可在同一个包中访问,但是这样就将这个包都封闭了,是没意义的。如果没public,就可以随意给文件起名,可以不和类名相同。
2、被public修饰的类与文件名必须同名的原因:
第一、java是被编译执行的,它在运行时并不是将你写的所有类都先加载一遍的,而是当遇到import或使用到了其他类的时候,才会去在文件目录中找相应的class文件的。
第二、对于一个public类。上面也说了,是可以被项目中的任何一个类引用的,只需通过import导入即可。既然是作为虚拟机入口的main函数要用public修饰而成为一个公共接口,那么将类名和文件名一一对应就可以方便虚拟机在相应的路径(包名)中找到相关的信息;但是你如果不这么做,虚拟机很难去找,开销也会跟着增大的。

简单总结:
public作为一个公共接口(此接口非interface这个接口),修饰作为虚拟机入口的main函数,就是为了方便虚拟机找到相应的类,从而节省开销。
作者: strawberry2013    时间: 2013-3-29 20:33
1.Java保存的文件名必须与类名一致;
2.如果文件中只有一个类,文件名必须与类名一致;
3.一个Java文件中只能有一个public类;
4.如果文件中不止一个类,文件名必须与public类名一致;
5.如果文件中不止一个类,而且没有public类,文件名可与任一类名一致
作者: 李尧    时间: 2013-3-29 22:12
因为 public 修饰的类是给其他的包访问的.
你可以试想这种情况:
其他的包需要访问这个类,而这个类还没有编译也就是没有class文件,而jvm需要找到源文件编译.但是类名和源文件名不一致,jvm如何通过包名去找到源文件?所以需要public修饰的类与源文件名一致.我想大概就是这样了.....
作者: 王俊杰    时间: 2013-3-30 13:01
这个问题也困扰过我。 后来我在网上找到了一个相对满意的答案。

我也像你一样试图弄清楚最根本的原理。未果。

这个博客里分析的还是很不错的。希望对你有所帮助。如果想寻求根本上的解答,可能要找到当初java编译器的设计者吧

http://blog.csdn.net/bareheadzzq/article/details/6562211

一个Java源文件中最多只能有一个public类,当有一个public类时,源文件名必
须与之一致,否则无法编译,如果源文件中没有一个public类,则文件名与类中没有一致性要求。
至于main()不是必须要放在public类中才能运行程序。
以上是通过实验得出的结论,个人认为到这里已经可以了,如果一定要追问到底,可能要问问java
平台的设计者了。或许,人家会说:这是java的设计和jvm的内部体系结构设计造成,这是一个规
范,没有为什么
作者: 山西_李帅    时间: 2013-3-30 15:00
没有关系的啦,文件名最好和主函数类名一致。启的有意义




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2