疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

那些java中的常用类(二)


 

 
本节将介绍剩下的几个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     }
复制代码
需要注意的是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类是java.io包下用于操作与平台无关的文件和目录,也就是说,不管是文件还是目录都是使用File类来操作的。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     }
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 }
复制代码