A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 赵崇友 中级黑马   /  2013-3-29 16:16  /  3542 人查看  /  16 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 赵崇友 于 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, 下载次数: 51)

图片1.png

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1 鼓励下!继续加油!

查看全部评分

16 个回复

倒序浏览
public  class  Test1//定义类名
{
public static void main(String[] args) //程序的入口(主方法)
{
System.out.println("Hello Java!");//打印Hello Java!语句
}
}
保存到D盘Test目录下,名为Test.java。

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
你保存的文件名是Test.java  而你在程序里面public class  后却是 Test1
回复 使用道具 举报
kelline 发表于 2013-3-29 16:28
你保存的文件名是Test.java  而你在程序里面public class  后却是 Test1

我知道,具体原因求解释
回复 使用道具 举报
你去掉class前的public  就可以了
回复 使用道具 举报
胡志超 发表于 2013-3-29 16:31
你去掉class前的public  就可以了

嗯嗯,求解释具体的原因。
回复 使用道具 举报
赵崇友 发表于 2013-3-29 16:34
嗯嗯,求解释具体的原因。

class前加public,那么.java名和类名必须保持一致,如果不加public那么就不用了
回复 使用道具 举报
如果你家public , 你的类名和文件名必须一样, 不加public 你的类名和保存的文件名可以不一样
回复 使用道具 举报
胡志超 发表于 2013-3-29 16:37
class前加public,那么.java名和类名必须保持一致,如果不加public那么就不用了 ...

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

这是语法问题,能解决掉,我是想了解加了public为什么要一致!其中的原理
回复 使用道具 举报
kelline 发表于 2013-3-29 16:40
那是java的命名规则, 再具体的就不知道了

嗯嗯,等大神的到来吧!!
回复 使用道具 举报
我不是大神,查了一点资料,以下是个人愚见,希望有帮助:
首先说明结论:一个编译单元(个人理解为执行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函数,就是为了方便虚拟机找到相应的类,从而节省开销。

评分

参与人数 1技术分 +2 收起 理由
黄玉昆 + 2 很给力!

查看全部评分

回复 使用道具 举报
1.Java保存的文件名必须与类名一致;
2.如果文件中只有一个类,文件名必须与类名一致;
3.一个Java文件中只能有一个public类;
4.如果文件中不止一个类,文件名必须与public类名一致;
5.如果文件中不止一个类,而且没有public类,文件名可与任一类名一致

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
因为 public 修饰的类是给其他的包访问的.
你可以试想这种情况:
其他的包需要访问这个类,而这个类还没有编译也就是没有class文件,而jvm需要找到源文件编译.但是类名和源文件名不一致,jvm如何通过包名去找到源文件?所以需要public修饰的类与源文件名一致.我想大概就是这样了.....
回复 使用道具 举报
这个问题也困扰过我。 后来我在网上找到了一个相对满意的答案。

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

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

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

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