那些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 } 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 }
本节只是简单介绍了一下枚举类,详细了解可参考:http://www.cnblogs.com/hemingwang0902/archive/2011/12/29/2306263.html