-
前言
在实际项目开发中,往往需要开发很多不同的类,能否方便高效地组织这些类对项目的开发与使用具有很重要的意义。Java中提供包( Package)将不同类组织起来进行管理,借助于包可以方便地组织自己的类代码,并将自己的代码与别人提供的代码库分开管理,使用包的目的之一就是可以在同一个项目中使用名称相同的类,假如两个开发人员不约而同地建立了两个相同名字的类,只要将其放置在不同的包中,就不会产生冲突。本文将从类的放置与导入两个方面进行介绍。
-
包的定义
要想将类放入指定的包中,就必须使用 package语句,语法如下
package <包名>;
package语句必须放在源文件的最前面,其之前不可以有其他任何语句。每个源文件中最多有一句 package语句,因为一个类不可能属于两个包,就如同不能把一件衣服同时放进两个箱子一样。包名可以是用点“ . ”分隔的一个序列,如 java . lang,这就表示此源文件中的类在java包下的lang子包中。在实际开发中,包可能分很多级,越复杂的系统,包越多,级也可能越多。
例如,下面代码将类 Sample321放在了 chapter03包中:
包实际上代表的是文件夹(目录路径)。有了包以后,将类文件放在不同的包中,方便管理,避免冲突。如果不将编译后的class文件放到相应的文件夹中,则无法运行。
运行在具体包中的类时要使用类名全称,就是包名与类名顺次用"."隔开,如果没有使用全称类名,则系统报“ java.lang.No Class DefFound Error 1”异常。
在运行程序时,要将当前目录设置为最外层的包文件夹所在的目录,而不是类文件所在目录, 否则在有些情况下运行可能报错,这取决于操作系统和机器的情况。另外,在开发中要注意不要 把类文件随意复制到别的目录中,否则将可能引起程序不能正常运行。
如果没有在源文件中使用package语句.那么这个源文件中的类就被放置在一个匿名包中。 匿名包是一个没有名字的包,代码编译后类文件与源文件在同一个目录中即可。在此节之前的章节中,定义的所有类都在匿名包中。
-
类的导入
当一个类要使用与自己处在同一个包巾的类时,直接访问即可。若要使用其他包中的类就必 须使用import语句,基本语法如下:
import <包名>.*;
import <包名>. 类名;
包名可以是由一个" . "分隔的序列,如 ” java.lang” 、“ java.util” 等,第一种语法表示要使用指定包中的所有类,但不包括子包中的类,也称为通配引入,“ * ”为通配符。第二种语法表示要使用指定包中一个特定的类。
一个源文件中根据需要可以有多句 Import语句。 Import语句要放在 package语句之后,类声明之前。如果有多个 Import语句多句 Import语句先后顺序无所谓。
下面的代码给出了一个简单使用 Import语句的例子:
import java.uti1.*;
import java. io.Inputstream;
多个 Import语句并不影响程序的运行性能。因为 Import语句只在编译的时候有作用。另外java.lang包中的类,系统是自动引入的,相当于每个源文件中系统都会在编译时自动加上“ Import java. lang.*”语句。另外,需要特别注意的是,不能使用星号(*)代替包,例如使用的导入语句是非法的:import java.*.*;
有“*”号代替所有包中的类就可以了,指定具体的类名岂不很不方便?是的,如果只使用一个包中的类或多个包中不同名称的类确实如此,但若要使用多个包中的同名类就不行了,本小节分如下两个方面对这个问题进行介绍:两个包中有同名类,但只用到其中一个及其他不同名的类两个包中有同名类,且都要使用。
1、两个包中有同名类,但只用到其中一个及其他不同名的类
例如, java.util和java.sql包中都有名称为Date的类,在程序中要同时使用这两个包中的其他很多类,但只用到 java.util包中的Date类,代码如下。
package chapter03;
import java.util.*;
import java.sql.*;
public class Sample3_22
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
Date d=new Date();
}
}
编译代码,系统会报Date类匹配失败,因为在源代码中用import语句引入了两个包中所有的类,两个包中都含有Date类,系统不知道应该匹配哪一个,如果只用java.until包中的Date类,可以增加一行:“ import java.until.Date ”。
2、两个包中含有同名类,且都要使用
如果要使用两个不同包中的同名类,只靠import就无法解决了,真正的解决办法是使用全称类名:
package chapter03;
import java.util.*;
import java.sql.*;
public class Sample3_22
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
java.util.Date d1=new java.util.Date();
java.sql.Date d2=new java.sql.Date(123);
}
}
-
静态导入
从Java SE 5.0 开始,导入语句不但可以导入类,还具有导入静态方法和静态成员变量的功能,不过需要在关键字“import”和包名之间添加关键字“static“,法如下:
import static <包名>.<类名>.*;
import static <包名>.<类名>.<具体方法/成员变量名>;
”*“还是代表通配符,不过这里表示的是指定类下面所有静态的方法成成员变量。如果要明确指明要使用的方法或成员变量,用第2行语法。碰到不同类下同名静态方法或成员变量时,解决冲突的方法类似上一小节,这里不再赞述。下面的例子说明了静态引入的使用,代码如下:
package chapter03;
import java.util.*;
import static java.lang.System.*;
import static java.lang.Math.sqrt;
public class Sample3_21
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
out.print("#####");
out.println("25.25的平方根:"+sqrt(25.25));
}
}
程序正常编译运行并打印出结果,实际上,并没有很多开发人员采用静态引入,因为这种代码编写形式非常容易降低代码的可读性,造成维护困难。因此,在使用此项功能时一定要注意不影响代码的可读性,否则有害无益。