*.Java 文件
问题:一个 ”.java” 源文件中是否可以包括多个类(不是内部类)?有什么限制?
答案:可以有多个类,但只能有一个 public 的类,并且 public 的类名必须与文件名相一致。一个文件中可以只有非 public 类,如果只有一个非 public 类,此类可以跟文件名不同。
为什么一个 java 源文件中只能有一个 public 类?
在 java 编程思想(第四版)一书中有这样 3 段话(6.4 类的访问权限):
1. 每个编译单元(文件)都只能有一个 public 类,这表示,每个编译单元都有单一的公共接口,用 public 类来表现。该接口可以按要求包含众多的支持包访问权限的类。如果在某个编译单元内有一个以上的 public 类,编译器就会给出错误信息。2.public 类的名称必须完全与含有该编译单元的文件名相同,包含大小写。如果不匹配,同样将得到编译错误。
3. 虽然不是很常用,但编译单元内完全不带 public 类也是可能的。在这种情况下,可以随意对文件命名。
总结相关的几个问题:
1、一个”.java”源文件中是否可以包括多个类(不是内部类)?有什么限制?
答:可以有多个类,但只能有一个 public 的类,并且 public 的类名必须与文件名相一致。
2、为什么一个文件中只能有一个 public 的类
答:编译器在编译时,针对一个 java 源代码文件(也称为“编译单元”)只会接受一个 public 类。否则报错。
3、在 java 文件中是否可以没有 public 类
答:public 类不是必须的,java 文件中可以没有 public 类。
4、为什么这个 public 的类的类名必须和文件名相同
答:是为了方便虚拟机在相应的路径中找到相应的类所对应的字节码文件。
Main 方法
主函数:是一个特殊的函数,作为程序的入口,可以被 JVM 调用
主函数的定义:
public:代表着该函数访问权限是最大的 static:代表主函数随着类的加载就已经存在了
void:主函数没有具体的返回值
main:不是关键字,但是一个特殊的单词,能够被 JVM 识别
(String[] args):函数的参数,参数类型是一个数组,该数组中的元素师字符串,字符串数组。main(String[] args) 字符串数组的 此时空数组的长度是 0,但也可以在 运行的时候向其中传入参数。
主函数时固定格式的,JVM 识别
主函数可以被重载,但是 JVM 只识别 main(String[] args),其他都是作为一般函数。这里面的 args 知识数组变量可以更改,其他都不能更改。
一个 java 文件中可以包含很多个类,每个类中有且仅有一个主函数,但是每个 java 文件中可以包含多个主函数,在运行时,需要指定 JVM 入口是哪个。例如一个类的主函数可以调用另一个类的主函数。不一定会使用 public 类的主函数。
外部类的访问权限
外部类只能用 public 和 default 修饰。
为什么要对外部类或类做修饰呢?
1. 存在包概念:public 和 default 能区分这个外部类能对不同包作一个划分(default 修饰的类,其他包中引入不了这个类,public 修饰的类才能被 import)2.protected 是包内可见并且子类可见,但是当一个外部类想要继承一个 protected 修饰的非同包类时,压根找不到这个类,更别提几层了
3.private 修饰的外部类,其他任何外部类都无法导入它。
//Java 中的文件名要和 public 修饰的类名相同,否则会报错
// 如果没有 public 修饰的类,则文件可以随意命名
public class Java 中的类文件 {
}
// 非公共开类的访问权限默认是包访问权限,不能用 private 和 protected
// 一个外部类的访问权限只有两种,一种是包内可见,一种是包外可见。
// 如果用 private 修饰,其他类根本无法看到这个类,也就没有意义了。
// 如果用 protected,虽然也是包内可见,但是如果有子类想要继承该类但是不同包时,
// 压根找不到这个类,也不可能继承它了,所以干脆用 default 代替。
class A{
}
Java 包的命名规则
以 java.* 开头的是 Java 的核心包,所有程序都会使用这些包中的类;以 javax. 开头的是扩展包,x 是 extension 的意思,也就是扩展。虽然 javax. 是对 java. 的优化和扩展,但是由于 javax. 使用的越来越多,很多程序都依赖于 javax.,所以 javax. 也是核心的一部分了,也随 JDK 一起发布。
以 org.* 开头的是各个机构或组织发布的包,因为这些组织很有影响力,它们的代码质量很高,所以也将它们开发的部分常用的类随 JDK 一起发布。
在包的命名方面,为了防止重名,有一个惯例:大家都以自己域名的倒写形式作为开头来为自己开发的包命名,例如百度发布的包会以 com.baidu. 开头,w3c 组织发布的包会以 org.w3c. 开头,微学苑发布的包会以 net.weixueyuan.* 开头……
组织机构的域名后缀一般为 org,公司的域名后缀一般为 com,可以认为 org. 开头的包为非盈利组织机构发布的包,它们一般是开源的,可以免费使用在自己的产品中,不用考虑侵权问题,而以 com. 开头的包往往由盈利性的公司发布,可能会有版权问题,使用时要注意。
import 的使用
Java import 以及 Java 类的搜索路径 如果你希望使用 Java 包中的类,就必须先使用 import 语句导入 语法为:
import package1[.package2…].classname;
package 为包名,classname 为类名。例如:
import java.util.Date; // 导入 java.util 包下的 Date 类
import java.util.Scanner; // 导入 java.util 包下的 Scanner 类
import javax.swing.*; // 导入 javax.swing 包下的所有类,* 表示所有类
</pre>
注意:
import 只能导入包所包含的类,而不能导入包。为方便起见,我们一般不导入单独的类,而是导入包下所有的类,例如 import java.util.*;。Java 编译器默认为所有的 Java 程序导入了 JDK 的 java.lang 包中所有的类(import java.lang.*;),其中定义了一些常用类,如 System、String、Object、Math 等,因此我们可以直接使用这些类而不必显式导入。但是使用其他类必须先导入。
前面讲到的”Hello World“程序使用了 System.out.println(); 语句,System 类位于 java.lang 包,虽然我们没有显式导入这个包中的类,但是 Java 编译器默认已经为我们导入了,否则程序会执行失败。
java 类的搜索路径 Java 程序运行时要导入相应的类,也就是加载 .class 文件的过程。假设有如下的 import 语句:
import p1.Test;
该语句表明要导入 p1 包中的 Test 类。安装 JDK 时,我们已经设置了环境变量 CLASSPATH 来指明类库的路径,它的值为 .;%JAVAHOME%lib,而 JAVAHOME 又为 D:Program Filesjdk1.7.071,所以 CLASSPATH 等价于 .;D:Program Filesjdk1.7.071lib。如果在第一个路径下找到了所需的类文件,则停止搜索,否则继续搜索后面的路径,如果在所有的路径下都未能找到所需的类文件,则编译或运行出错。
你可以在 CLASSPATH 变量中增加搜索路径,例如 .;%JAVA_HOME%lib;C:javalib,那么你就可以将类文件放在 C:javalib 目录下,Java 运行环境一样会找到。
用户自己写的类可以通过 IDE 指定编译后的 class 文件的输出目录,appclassloader 会到指定目录进行类的加载
下面是一个 import 两种访问权限的类的实例:
package com.javase.Java 中的类. 一个包;
public class 全局访问 {
}
package com.javase.Java 中的类. 一个包;
class 包访问权限 {
}
package com.javase.Java 中的类;
//import 可以导入基础包以及公开的类,需要使用类名的全路径
// 并且在导入某个包.* 时,是不会把子包的类给导进来的,这样可以避免导入错误。
// 注意
//import com.javase.Java 中的类. 一个包. 包访问权限;
// 这个导入会报错,因为这个类没有用 public 修饰,无法用 import 导入。
import com.javase.Java 中的类. 一个包. 全局访问;// 可以导入。