本节将介绍剩下的几个java常用类。
3.Object类
- Object类存储在java.lang包中,是所有java类(Object类除外)的终极父类。当然,数组也继承了Object类,但是,接口和枚举类是不继承Object类的。
- java的任何类都继承了Object类的成员方法,并且可以重写不被final修饰的方法。
- Object类包含的一些成员方法:
- Object()方法:一般情况下,java通过new关键字来创建对象,而这是通过类中的构造方法来实现的。因此,java中规定:在类的定义过程中,对于未定义构造方法的类,默认会有一个无参的构造方法,作为所有java类的父类,Object自然也要体现这一特性。所以,在Object的源码中没有给出构造方法的具体定义,但实际上这个构造方法是存在的。
- clone()方法:这个方法可以产生一个相同的类,并且返回给调用者。这是一个native方法,由C语言实现,使用时需要注意:当代码执行的时候,将会检查调用对象的类(或者父类)是否实现了
java.lang.Cloneable
- 接口(
Object
- 类不实现
Cloneable
- )。如果没有实现这个接口,
clone()
- 将会抛出一个检查异常()——
java.lang.CloneNotSupportedException
- ,如果实现了这个接口,
clone()
- 会创建一个新的对象,并将原来对象的内容复制到新对象,最后返回这个新对象的引用。
- finalize()方法:
finalize()也是一个native
- 方法,并且这个方法可以被子类对象所覆盖,然后作为一个终结者,当GC被调用的时候完成最后的清理工作(例如释放系统资源之类)。默认的
finalize()
- 方法什么也不做,当被调用时直接返回。
- Object还提供了wait、notify、notifyAll几个方法,用于控制线程的暂停和运行,这将在以后的文章中进行详细介绍。
- clone()方法的使用示例:
1 /*
2 * 定义一个Person类,并实现Cloneable接口
3 */
4 public class Person implements Cloneable {
5
6 @Override
7 protected Object clone() throws CloneNotSupportedException {
8 // TODO Auto-generated method stub
9 return super.clone();
10 }
11
12 public String name;
13 }
1 public class CloneTest {
2 public static void main(String[] args) throws CloneNotSupportedException {
3 //创建一个Person对象,并初始化
4 Person p1 = new Person("hello");
5 System.out.println(p1.name);//hello
6
7 /*
8 * 调用clone方法,对p1对象进行克隆
9 * 注意:当代码执行的时候,将会检查调用对象的类(或者父类)是否实现了java.lang.Cloneable接口(Object类不实现Cloneable)。
10 * 如果没有实现这个接口,clone()将会抛出一个检查异常()——java.lang.CloneNotSupportedException,
11 * 如果实现了这个接口,clone()会创建一个新的对象,并将原来对象的内容复制到新对象,最后返回这个新对象的引用。
12 */
13 //所以,此处会先检查Person类是否实现了Cloneable,即重写clone()方法。
14 Person p2 = (Person) p1.clone();
15 System.out.println(p2.name);//hello
16
17 }
18
19 }
4.Math类
Math类提供了基本数学函数的计算方法,并且Math类中所有的成员变量(主要指PI和E)和成员方法都是静态的,可以通过类名直接调用。这里只是简单列举一些:
1 public class MathDemo {
2
3 public static void main(String[] args) {
4 /**
5 * abs求绝对值
6 */
7 System.out.println(Math.abs(-10.4)); //10.4
8 System.out.println(Math.abs(10.1)); //10.1
9
10 /**
11 * ceil天花板的意思,就是返回大的值,注意一些特殊值
12 */
13 System.out.println(Math.ceil(-10.1)); //-10.0
14 System.out.println(Math.ceil(10.7)); //11.0
15 System.out.println(Math.ceil(-0.7)); //-0.0
16 System.out.println(Math.ceil(0.0)); //0.0
17 System.out.println(Math.ceil(-0.0)); //-0.0
18
19 /**
20 * floor地板的意思,就是返回小的值
21 */
22 System.out.println(Math.floor(-10.1)); //-11.0
23 System.out.println(Math.floor(10.7)); //10.0
24 System.out.println(Math.floor(-0.7)); //-1.0
25 System.out.println(Math.floor(0.0)); //0.0
26 System.out.println(Math.floor(-0.0)); //-0.0
27
28 /**
29 * max 两个中返回大的值,min和它相反,就不举例了
30 */
31 System.out.println(Math.max(-10.1, -10)); //-10.0
32 System.out.println(Math.max(10.7, 10)); //10.7
33 System.out.println(Math.max(0.0, -0.0)); //0.0
34
35 /**
36 * random 取得一个大于或者等于0.0小于不等于1.0的随机数
37 */
38 System.out.println(Math.random()); //0.08417657924317234
39 System.out.println(Math.random()); //0.43527904004403717
40
41 /**
42 * rint 四舍五入,返回double值
43 * 注意.5的时候会取偶数
44 */
45 System.out.println(Math.rint(10.1)); //10.0
46 System.out.println(Math.rint(10.7)); //11.0
47 System.out.println(Math.rint(11.5)); //12.0
48 System.out.println(Math.rint(10.5)); //10.0
49 System.out.println(Math.rint(10.51)); //11.0
50 System.out.println(Math.rint(-10.5)); //-10.0
51 System.out.println(Math.rint(-11.5)); //-12.0
52 System.out.println(Math.rint(-10.51)); //-11.0
53 System.out.println(Math.rint(-10.6)); //-11.0
54 System.out.println(Math.rint(-10.2)); //-10.0
55
56 /**
57 * round 四舍五入,float时返回int值,double时返回long值
58 */
59 System.out.println(Math.round(10.1)); //10
60 System.out.println(Math.round(10.7)); //11
61 System.out.println(Math.round(10.5)); //11
62 System.out.println(Math.round(10.51)); //11
63 System.out.println(Math.round(-10.5)); //-10
64 System.out.println(Math.round(-10.51)); //-11
65 System.out.println(Math.round(-10.6)); //-11
66 System.out.println(Math.round(-10.2)); //-10
67
68 /*
69 * 指数函数的计算方法,返回double值
70 * 注意Math.log()是计算以e为底数的自然对数
71 */
72 System.out.println(Math.pow(Math.E, 2));//e^2
73 System.out.println(Math.sqrt(25));//5.0
74 System.out.println(Math.exp(2));//e^2
75 System.out.println(Math.log(Math.pow(Math.E, 2)));//2.0
76 System.out.println(Math.log10(100));//2.0
77
78 }
View Code
需要注意的是Math类中的取整方法:rint和round。
- rint遇到x.5的时候会取偶数
- round(x) = floor(x+0.5)
5.Random类
Random类用于生成伪随机数,它有两个构造器:一个构造器使用默认的种子(系统当前时间的毫秒值);另一个构造器需要程序员显示的传入一个long型的参数作为种子。
1 public static void main(String[] args) {
2
3 //使用默认种子的构造器,以系统当前时间的毫秒数作为种子
4 Random random = new Random();
5 for (int i = 0; i < 10; i++) {
6 System.out.print(random.nextInt(10)+" ");
7 }//5 0 2 6 5 0 4 1 4 9
8
9 /*使用带参数的构造器,传入一个long型整数作为种子
10 *需要注意的是:
11 * 相同种子数的Random对象,相同次数生成的随机数字是完全相同的。
12 * 即是,两个种子数相同的Random对象,第一次生成的随机数完全相同,第二次生成的随机数也完全相同
13 * 这点在生成多个随机数字时需要特别注意。
14 */
15 Random r1 = new Random(10);
16 Random r2 = new Random(10);
17 System.out.println(r1.nextInt() == r2.nextInt());//true
18 System.out.println(r1.nextInt() == r2.nextInt());//true
19
20 }
因此,为了避免两个Random对象产生相同的随机数序列,我们通常使用系统当前时间作为种子来生成随机数。而且,Random类还提供了一些其他类型的随机数生成方法,如nextDouble、nextFloat、nextLong、nextBoolean等。
1 Random random = new Random();
2
3 //nextDouble方法,产生[0.0,1.0)之间的double型随机数
4 //注意:Math类中的random方法就是调用Random类中的nextDouble方法实现的。
5 for (int i = 0; i < 10; i++) {
6 System.out.print(random.nextDouble()+" ");
7 }
8 System.out.println();
9
10 //nextFloat方法,产生[0.0,1.0)之间的float型随机数
11 for (int i = 0; i < 10; i++) {
12 System.out.print(random.nextFloat()+" ");
13 }
14 System.out.println();
15
16 //nextLong方法,产生long型的随机整数
17 for (int i = 0; i < 10; i++) {
18 System.out.print(random.nextLong()+" ");
19 }
20 System.out.println();
21
22 //nextBoolean方法,产生随机的布尔数
23 for (int i = 0; i < 10; i++) {
24 System.out.print(random.nextBoolean());
25 }
26
6.File类
File类不能访问文件的内容,需要通过输入/输出流来访问。
- 构造方法:File(String pathname)、File(String parent, String child)、File(File parent, String child)、File(URI uri)
- 创建文件和目录:createNewFile() 文件不存在则创建并返回true,否则返回false、mkdir()创建目录、mkdirs()创建多级目录
- 删除文件和目录:delete()、deleteOnExit()
- 文件和目录信息获取:getName()、getPath()、getAbsolutePath()、getAbsoluteFile()、getParent()、getParentFile()等等。
- 获取指定目录下文件列表:listFiles()、list()
- 文件过滤:list(FilenameFilter filter)、listFiles(FilenameFilter filter)、listFiles(FileFilter filter),代码示例如下:
1 /*
2 * 从根目录开始搜索符合条件的文件
3 */
4 public static void main(String[] args){
5 File[] files =File.listRoots();
6 for(File file:files){
7 System.out.println(file);
8 if(file.length()>0){
9 String[] filenames =file.list(new FilenameFilter(){
10 //file 过滤目录 name 文件名
11 public boolean accept(File file,String filename){
12 return filename.endsWith(".mp3");
13 }
14 });
15 for(String filename:filenames){
16 System.out.println(filename);
17 }
18 }
19 }
20 }
21
22
23 public static void main(String[] args) {
24 // System.out.println(System.getProperty("user.dir"));
25
26 //先获取文件列表,再进行逐个筛选
27 File fileRoot = new File("D:\\...\\codeAnal");
28 File[] files = fileRoot.listFiles();
29 for(File file: files){
30 if(file.getName().startsWith("C")){
31 System.out.println(file.getName());
32 }
33 }
34 }
7.枚举类(Enum)
在一些特定的情况下,某个类的对象是有限而且固定的,例如季节类,它只有四个对象,再例如星期类,只有七个对象等等。这种实例对象有限而且固定的类在java中称为枚举类。
一、手动实现一个枚举类
一般来说有下面几个步骤:
- 将枚举类的构造器定义为private,使得其它类不可自行创建该类的实例对象;
- 将这个类的所有可能的实例对象用public static final来修饰,即定义为该类的静态常量;
- 在必要的情况下,提供一些静态方法,允许其他类通过指定参数来获取指定的实例对象。
代码示例如下:
1 /*
2 * 这是一个枚举类,只有四个实例对象
3 */
4 public class Season {
5
7 //将season类定义成私有的,将其属性也定义成final
8 private final String name;
9 private final String desc;
10 public static final Season SPRIGN = new Season("春天", "春天来了");
11 public static final Season SUMMER = new Season("夏天", "夏天来了");
12 public static final Season FALL = new Season("秋天", "秋天来了");
13 public static final Season WINTER = new Season("冬天", "冬天来了");
14
15 private Season (String name, String desc) {
16 this.name = name;
17 this.desc = desc;
18 }
19
20 //定义一个获取season对象的方法,这是一个静态工厂方法
21 public static Season getSeason(int seasonNum){
22 switch(seasonNum){
23 case 1: return SPRIGN;
24 case 2: return SUMMER;
25 case 3: return FALL;
26 case 4: return WINTER;
27 default: return null;
28 }
29 }
30
31 public String getDesc() {
32 return desc;
33 }
34
35 public String getName() {
36 return name;
37 }
38
39 @Override
40 public String toString() {
41 return "Season [name=" + name + ", desc=" + desc + "]";
42 }
43 }
1 public class EnumDemo {
2 public static void main(String[] args) {
3 //获取枚举类的实例对象
4 System.out.println(Season.getSeason(1).toString());//Season [name=春天, desc=春天来了]
5 System.out.println(Season.SPRIGN.toString());//Season [name=春天, desc=春天来了]
6 System.out.println(Season.FALL.toString());//Season [name=秋天, desc=秋天来了]
7 }
8
9 }
使用枚举类可以增加程序的健壮性,能够避免随意地创建对象。
二、枚举类的简单使用
JDK1.5新增了enum关键字,其作用类似于class和interface关键字,将生成一个枚举类,即一种特殊的java类。这种枚举类与其他一些普通类有如下简单区别:
- 使用enum定义的枚举类默认继承了java.lang.Enum类,而不是继承Object类。
- 枚举类的构造器只能使用private关键字来修饰,如果省略此关键字,则默认使用private修饰。
- 枚举类中的所有实例必须显示列出,而且对于列出的实例,系统都会自动加上public static final修饰,无序程序员手动添加。
- 所有枚举类都提供了一个values方法,用于遍历所有的枚举值。
代码示例:
1 /*
2 * 定义一个枚举类
3 */
4 public enum SeasonNum {
5 SPRING,SUMMER,FALL,WINTER;
6 }
1 public class EnumDemo {
2
3 public static void main(String[] args) {
4
5 //通过values方法遍历枚举值,即枚举类的所有实例
6 for(SeasonNum season: SeasonNum.values()){
7 System.out.print(season+" ");
8 }//SPRING SUMMER FALL WINTER
9
10 System.out.println();
11 judge(SeasonNum.SPRING);//春天来了
12
13 }
14
15 private static void judge(SeasonNum season) {
16
17 switch (season) {
18 case SPRING:
19 System.out.println("春天来了");
20 break;
21 case SUMMER:
22 System.out.println("夏天来了");
23 break;
24 case FALL:
25 System.out.println("秋天来了");
26 break;
27 case WINTER:
28 System.out.println("冬天来了");
29 break;
30 default:
31 break;
32 }
33 }
34 }
三、实现接口的枚举类
枚举类可以实现一个或者多个接口,与普通类一样,枚举类实现接口时也需要实现该接口所包含的方法。但是不同的是:如果需要每个枚举值在调用接口中的方法时呈现不同的行为方式,则可以让每个枚举值分别按照自己的方式来实现该方法。每个枚举值提供不同的实现方式,从而让不同枚举值调用该方法时具有不同的行为方式。
代码示例:
1 /*
2 * 定义一个性别的接口类
3 */
4 public interface GenderInfo {
5
6 void info();
7 }
1 /*
2 * 定义一个性别的枚举类,实现GenderInfo接口
3 */
4 public enum Gender implements GenderInfo {
5
6 //此处的枚举值必须调用对应的构造器来实现,并且不同的枚举值提供不同的实现方式
7 MALE("男"){
8 @Override
9 public void info() {
10 System.out.println("这是一个男性的枚举值");
11 }
12 },
13
14 FEMALE("女"){
15 @Override
16 public void info() {
17 System.out.println("这是一个女性的枚举值");
18 }
19 };
20
21 private final String name;
22 //自定义枚举类的构造器,访问修饰符必须为private
23 private Gender(String name){
24 this.name = name;
25 }
26
27 }
1 /*
2 * 接口枚举类的测试
3 */
4 public class GenderEnumDemo {
5
6 public static void main(String[] args) {
7 //通过类名直接获取枚举类的实例对象,然后调用info方法
8 Gender.MALE.info();//输出:这是一个男性的枚举值
9 Gender.FEMALE.info();//输出:这是一个男女性的枚举值
10 }
11 }