Java Learning_Note #3
Java Learning Note_3
1.一些常用类与输入输出获取
1.1 数字类
1.1.1 Number类
- 由编译器特别支持的包装称为装箱,所以当内置数据类型被当作对象使用的时候,编译器会把内置类型装箱为包装类
- Java 语言为每一个内置数据类型提供了对应的包装类,所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类 Number 的子类,Number 类属于 java.lang 包
1.1.2 Math类
- Java 的 Math 包含了用于执行基本数学运算的属性和方法,如初等指数、对数、平方根和三角函数
- Math 的方法都被定义为 static 形式,通过 Math 类可以在主函数中直接调用
public class Test {
public static void main (String []args)
{
System.out.println("90 度的正弦值:" + Math.sin(Math.PI/2));
System.out.println("0度的余弦值:" + Math.cos(0));
System.out.println("60度的正切值:" + Math.tan(Math.PI/3));
System.out.println("1的反正切值: " + Math.atan(1));
System.out.println("π/2的角度值:" + Math.toDegrees(Math.PI/2));
System.out.println(Math.PI);
}
}
1.1.3 Number&Math类常用方法
| 序号 | 方法与描述 |
|---|---|
| 1 | xxxValue() 将 Number 对象转换为xxx数据类型的值并返回。 |
| 2 | compareTo() 将number对象与参数比较。 |
| 3 | equals() 判断number对象是否与参数相等。 |
| 4 | valueOf() 返回一个 Number 对象指定的内置数据类型 |
| 5 | toString() 以字符串形式返回值。 |
| 6 | parseInt() 将字符串解析为int类型。 |
| 7 | abs() 返回参数的绝对值。 |
| 8 | ceil() 返回大于等于( >= )给定参数的的最小整数,类型为双精度浮点型。 |
| 9 | floor() 返回小于等于(<=)给定参数的最大整数 。 |
| 10 | rint() 返回与参数最接近的整数。返回类型为double。 |
| 11 | round() 它表示四舍五入,算法为 Math.floor(x+0.5),即将原来的数字加上 0.5 后再向下取整,所以,Math.round(11.5) 的结果为12,Math.round(-11.5) 的结果为-11。 |
| 12 | min() 返回两个参数中的最小值。 |
| 13 | max() 返回两个参数中的最大值。 |
| 14 | exp() 返回自然数底数e的参数次方。 |
| 15 | log() 返回参数的自然数底数的对数值。 |
| 16 | pow() 返回第一个参数的第二个参数次方。 |
| 17 | sqrt() 求参数的算术平方根。 |
| 18 | sin() 求指定double类型参数的正弦值。 |
| 19 | cos() 求指定double类型参数的余弦值。 |
| 20 | tan() 求指定double类型参数的正切值。 |
| 21 | asin() 求指定double类型参数的反正弦值。 |
| 22 | acos() 求指定double类型参数的反余弦值。 |
| 23 | atan() 求指定double类型参数的反正切值。 |
| 24 | atan2() 将笛卡尔坐标转换为极坐标,并返回极坐标的角度值。 |
| 25 | toDegrees() 将参数转化为角度。 |
| 26 | toRadians() 将角度转换为弧度。 |
| 27 | random() 返回一个随机数。 |
1.2 字符、字符串类
1.2.1 Character类
-
Character类提供了一系列方法来操纵字符
-
可以使用Character的构造方法创建一个Character类对象:
Character ch = new Character('a'); -
将一个char类型的参数传递给需要一个Character类型参数的方法时,那么编译器会自动地将char类型参数转换为Character对象(装箱):
// 原始字符 'a' 装箱到 Character 对象 ch 中 Character ch = 'a'; // 原始字符 'x' 用 test 方法装箱 // 返回拆箱的值到 'c' char c = test('x'); -
方法:
序号 方法与描述 1 isLetter() 是否是一个字母 2 isDigit() 是否是一个数字字符 3 isWhitespace() 是否是一个空白字符 4 isUpperCase() 是否是大写字母 5 isLowerCase() 是否是小写字母 6 toUpperCase() 指定字母的大写形式 7 toLowerCase() 指定字母的小写形式 8 toString() 返回字符的字符串形式,字符串的长度仅为1
1.2.2 String类
-
Java 提供了 String 类来创建和操作字符串
-
String 类是不可改变的,所以你一旦创建了 String 对象,那它的值就无法改变
-
创建字符串:
-
直接赋值:(编译器会使用该字符串常量创建一个 String 对象)
String str = "Runoob"; -
使用关键字和构造方法来创建 String 对象:
String str2=new String("Runoob"); -
String 创建的字符串存储在公共池中,而 new 创建的字符串对象在堆上:
String s1 = "Runoob"; // String 直接创建 String s2 = "Runoob"; // String 直接创建 String s3 = s1; // 相同引用 String s4 = new String("Runoob"); // String 对象创建 String s5 = new String("Runoob"); // String 对象创建
-
String 类有 11 种构造方法,这些方法提供不同的参数来初始化字符串,比如提供一个字符数组参数:
public class StringDemo{ public static void main(String args[]){ char[] helloArray = { 'r', 'u', 'n', 'o', 'o', 'b'}; String helloString = new String(helloArray); System.out.println( helloString ); } }
-
-
字符串长度:
//使用的访问器方法是 length() 方法,它返回字符串对象包含的字符数 public class StringDemo { public static void main(String args[]) { String site = "www.runoob.com"; int len = site.length(); System.out.println( "菜鸟教程网址长度 : " + len ); } } -
连接字符串:
-
string1.concat(string2); //返回 string2 连接 string1 的新字符串 -
"Hello," + " runoob" + "!" //更常用的是使用'+'操作符来连接字符串
-
-
创建格式化字符串:
-
//printf()格式化数字,用于一次输出 System.out.printf("浮点型变量的值为 " + "%f, 整型变量的值为 " + " %d, 字符串变量的值为 " + "is %s", floatVar, intVar, stringVar); -
//String 类的静态方法 format() 能用来创建可复用的格式化字符串,而不仅仅是用于一次打印输出 String fs; fs = String.format("浮点型变量的值为 " + "%f, 整型变量的值为 " + " %d, 字符串变量的值为 " + " %s", floatVar, intVar, stringVar);
-
-
String方法:
SN(序号) 方法描述 1 char charAt(int index) 返回指定索引处的 char 值。 2 int compareTo(Object o) 把这个字符串和另一个对象比较。 3 int compareTo(String anotherString) 按字典顺序比较两个字符串。 4 int compareToIgnoreCase(String str) 按字典顺序比较两个字符串,不考虑大小写。 5 String concat(String str) 将指定字符串连接到此字符串的结尾。 6 boolean contentEquals(StringBuffer sb) 当且仅当字符串与指定的StringBuffer有相同顺序的字符时候返回真。 7 [static String copyValueOf(char] data) 返回指定数组中表示该字符序列的 String。 8 [static String copyValueOf(char] data, int offset, int count) 返回指定数组中表示该字符序列的 String。 9 boolean endsWith(String suffix) 测试此字符串是否以指定的后缀结束。 10 boolean equals(Object anObject) 将此字符串与指定的对象比较。 11 boolean equalsIgnoreCase(String anotherString) 将此 String 与另一个 String 比较,不考虑大小写。 12 [byte] getBytes() 使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 13 [byte] getBytes(String charsetName) 使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 14 [void getChars(int srcBegin, int srcEnd, char] dst, int dstBegin) 将字符从此字符串复制到目标字符数组。 15 int hashCode() 返回此字符串的哈希码。 16 int indexOf(int ch) 返回指定字符在此字符串中第一次出现处的索引。 17 int indexOf(int ch, int fromIndex) 返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索。 18 int indexOf(String str) 返回指定子字符串在此字符串中第一次出现处的索引。 19 int indexOf(String str, int fromIndex) 返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。 20 String intern() 返回字符串对象的规范化表示形式。 21 int lastIndexOf(int ch) 返回指定字符在此字符串中最后一次出现处的索引。 22 int lastIndexOf(int ch, int fromIndex) 返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索。 23 int lastIndexOf(String str) 返回指定子字符串在此字符串中最右边出现处的索引。 24 int lastIndexOf(String str, int fromIndex) 返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。 25 int length() 返回此字符串的长度。 26 boolean matches(String regex) 告知此字符串是否匹配给定的正则表达式。 27 boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) 测试两个字符串区域是否相等。 28 boolean regionMatches(int toffset, String other, int ooffset, int len) 测试两个字符串区域是否相等。 29 String replace(char oldChar, char newChar) 返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。 30 String replaceAll(String regex, String replacement) 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。 31 String replaceFirst(String regex, String replacement) 使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。 32 [String] split(String regex) 根据给定正则表达式的匹配拆分此字符串。 33 [String] split(String regex, int limit) 根据匹配给定的正则表达式来拆分此字符串。 34 boolean startsWith(String prefix) 测试此字符串是否以指定的前缀开始。 35 boolean startsWith(String prefix, int toffset) 测试此字符串从指定索引开始的子字符串是否以指定前缀开始。 36 CharSequence subSequence(int beginIndex, int endIndex) 返回一个新的字符序列,它是此序列的一个子序列。 37 String substring(int beginIndex) 返回一个新的字符串,它是此字符串的一个子字符串。 38 String substring(int beginIndex, int endIndex) 返回一个新字符串,它是此字符串的一个子字符串。 39 [char] toCharArray() 将此字符串转换为一个新的字符数组。 40 String toLowerCase() 使用默认语言环境的规则将此 String 中的所有字符都转换为小写。 41 String toLowerCase(Locale locale) 使用给定 Locale 的规则将此 String 中的所有字符都转换为小写。 42 String toString() 返回此对象本身(它已经是一个字符串!)。 43 String toUpperCase() 使用默认语言环境的规则将此 String 中的所有字符都转换为大写。 44 String toUpperCase(Locale locale) 使用给定 Locale 的规则将此 String 中的所有字符都转换为大写。 45 String trim() 返回字符串的副本,忽略前导空白和尾部空白。 46 static String valueOf(primitive data type x) 返回给定data type类型x参数的字符串表示形式。 47 contains(CharSequence chars) 判断是否包含指定的字符系列。 48 isEmpty() 判断字符串是否为空。
1.2.3 StringBuffer 和 StringBuilder 类
- 和 String 类不同,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象
- 和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问),但有速度优势,因此多数情况使用StringBuilder;在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类
public class RunoobTest{
public static void main(String args[]){
StringBuilder sb = new StringBuilder(10);
sb.append("Runoob..");
System.out.println(sb);
sb.append("!");
System.out.println(sb);
sb.insert(8, "Java");
System.out.println(sb);
sb.delete(5,8);
System.out.println(sb);
}
}
/**实例编译运行结果如下:
Runoob..
Runoob..!
Runoob..Java!
RunooJava!
**/
-
StringBuffer常用方法:
序号 方法描述 1 public StringBuffer append(String s) 将指定的字符串追加到此字符序列。 2 public StringBuffer reverse() 将此字符序列用其反转形式取代。 3 public delete(int start, int end) 移除此序列的子字符串中的字符。 4 public insert(int offset, int i) 将 int参数的字符串表示形式插入此序列中。5 insert(int offset, String str) 将 str参数的字符串插入此序列中。6 replace(int start, int end, String str) 使用给定 String中的字符替换此序列的子字符串中的字符。
1.3 日期时间类
1.3.1 Date类
-
java.util 包提供了 Date 类来封装当前的日期和时间
-
构造函数:
-
使用当前日期和时间来初始化对象:
Date( ) -
接收一个参数,该参数是从 1970 年 1 月 1 日起的毫秒数:
Date(long millisec)
-
-
Date方法:
序号 方法和描述 1 boolean after(Date date) 若当调用此方法的Date对象在指定日期之后返回true,否则返回false。 2 boolean before(Date date) 若当调用此方法的Date对象在指定日期之前返回true,否则返回false。 3 Object clone( ) 返回此对象的副本。 4 int compareTo(Date date) 比较当调用此方法的Date对象和指定日期。两者相等时候返回0。调用对象在指定日期之前则返回负数。调用对象在指定日期之后则返回正数。 5 int compareTo(Object obj) 若obj是Date类型则操作等同于compareTo(Date) 。否则它抛出ClassCastException。 6 boolean equals(Object date) 当调用此方法的Date对象和指定日期相等时候返回true,否则返回false。 7 long getTime( ) 返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。 8 int hashCode( ) 返回此对象的哈希码值。 9 void setTime(long time) 用自1970年1月1日00:00:00 GMT以后time毫秒数设置时间和日期。 10 String toString( ) 把此 Date 对象转换为以下形式的 String: dow mon dd hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)。
1.3.2 SimpleDateFormat类
-
SimpleDateFormat 是一个以语言环境敏感的方式来格式化和分析日期的类
-
允许你选择任何用户自定义日期时间格式来运行
import java.util.*;
import java.text.*;
public class DateDemo {
public static void main(String[] args) {
Date dNow = new Date( );
SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");
System.out.println("当前时间为: " + ft.format(dNow));
}
}
-
时间模式字符串用来指定时间格式:
字母 描述 示例 G 纪元标记 AD y 四位年份 2001 M 月份 July or 07 d 一个月的日期 10 h A.M./P.M. (1~12)格式小时 12 H 一天中的小时 (0~23) 22 m 分钟数 30 s 秒数 55 S 毫秒数 234 E 星期几 Tuesday D 一年中的日子 360 F 一个月中第几周的周几 2 (second Wed. in July) w 一年中第几周 40 W 一个月中第几周 1 a A.M./P.M. 标记 PM k 一天中的小时(1~24) 24 K A.M./P.M. (0~11)格式小时 10 z 时区 Eastern Standard Time ' 文字定界符 Delimiter " 单引号 ` -
printf格式化日期:(它以
%t开头并且以下面表格中的一个字母结尾)转 换 符 说 明 示 例 c 包括全部日期和时间信息 星期六 十月 27 14:21:20 CST 2007 F "年-月-日"格式 2007-10-27 D "月/日/年"格式 10/27/07 r "HH:MM:SS PM"格式(12时制) 02:25:51 下午 T "HH:MM:SS"格式(24时制) 14:28:16 R "HH:MM"格式(24时制) 14:28
import java.util.Date;
public class DateDemo {
public static void main(String[] args) {
// 初始化 Date 对象
Date date = new Date();
//c的使用
System.out.printf("全部日期和时间信息:%tc%n",date);
//f的使用
System.out.printf("年-月-日格式:%tF%n",date);
//d的使用
System.out.printf("月/日/年格式:%tD%n",date);
//r的使用
System.out.printf("HH:MM:SS PM格式(12时制):%tr%n",date);
//t的使用
System.out.printf("HH:MM:SS格式(24时制):%tT%n",date);
//R的使用
System.out.printf("HH:MM格式(24时制):%tR",date);
}
}
/**
全部日期和时间信息:星期一 九月 10 10:43:36 CST 2012
年-月-日格式:2012-09-10
月/日/年格式:09/10/12
HH:MM:SS PM格式(12时制):10:43:36 上午
HH:MM:SS格式(24时制):10:43:36
HH:MM格式(24时制):10:43
**/
-
利用一个格式化字符串指出要被格式化的参数的索引,索引必须紧跟在%后面,而且必须以$结束:
import java.util.Date; public class DateDemo { public static void main(String[] args) { // 初始化 Date 对象 Date date = new Date(); // 使用toString()显示日期和时间 System.out.printf("%1$s %2$tB %2$td, %2$tY", "Due date:", date); } } -
可以使用 < 标志。它表明先前被格式化的参数要被再次使用:
定义日期格式的转换符可以使日期通过指定的转换符生成新字符串import java.util.Date; public class DateDemo { public static void main(String[] args) { // 初始化 Date 对象 Date date = new Date(); // 显示格式化时间 System.out.printf("%s %tB %<te, %<tY", "Due date:", date); } } -
定义日期格式的转换符可以使日期通过指定的转换符生成新字符串:
import java.util.*; public class DateDemo { public static void main(String[] args) { Date date=new Date(); //b的使用,月份简称 String str=String.format(Locale.US,"英文月份简称:%tb",date); System.out.println(str); System.out.printf("本地月份简称:%tb%n",date); //B的使用,月份全称 str=String.format(Locale.US,"英文月份全称:%tB",date); System.out.println(str); System.out.printf("本地月份全称:%tB%n",date); //a的使用,星期简称 str=String.format(Locale.US,"英文星期的简称:%ta",date); System.out.println(str); //A的使用,星期全称 System.out.printf("本地星期的简称:%tA%n",date); //C的使用,年前两位 System.out.printf("年的前两位数字(不足两位前面补0):%tC%n",date); //y的使用,年后两位 System.out.printf("年的后两位数字(不足两位前面补0):%ty%n",date); //j的使用,一年的天数 System.out.printf("一年中的天数(即年的第几天):%tj%n",date); //m的使用,月份 System.out.printf("两位数字的月份(不足两位前面补0):%tm%n",date); //d的使用,日(二位,不够补零) System.out.printf("两位数字的日(不足两位前面补0):%td%n",date); //e的使用,日(一位不补零) System.out.printf("月份的日(前面不补0):%te",date); } } -
解析字符串为时间(parse()试图按照给定的SimpleDateFormat 对象的格式化存储来解析字符串)
import java.util.*; import java.text.*; public class DateDemo { public static void main(String[] args) { SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd"); String input = args.length == 0 ? "1818-11-11" : args[0]; System.out.print(input + " Parses as "); Date t; try { t = ft.parse(input); System.out.println(t); } catch (ParseException e) { System.out.println("Unparseable using " + ft); } } }$ java DateDemo 1818-11-11 Parses as Wed Nov 11 00:00:00 GMT 1818 $ java DateDemo 2007-12-01 2007-12-01 Parses as Sat Dec 01 00:00:00 GMT 2007
1.3.3 Java休眠/延时(sleep)
-
sleep()使当前线程进入停滞状态(阻塞当前线程),让出CPU的使用,不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会
-
实例:(3s休眠且测量时间间隔-ms为单位)
import java.util.*; public class DiffDemo { public static void main(String[] args) { try { long start = System.currentTimeMillis( ); System.out.println(new Date( ) + "\n"); Thread.sleep(5*60*10); //休眠时间3s System.out.println(new Date( ) + "\n"); long end = System.currentTimeMillis( ); long diff = end - start; System.out.println("Difference is : " + diff); } catch (Exception e) { System.out.println("Got an exception!"); } } }
1.3.4 Calendar类
-
设置和获取日期数据的特定部分,比Date类强大很多,而且在实现方式上也比Date类要复杂一些
-
Calendar类是一个抽象类,在实际使用时实现特定的子类的对象,创建对象的过程对程序员来说是透明的,只需要使用getInstance方法创建即可
-
创建一个代表系统当前日期的Calendar对象:
Calendar c = Calendar.getInstance();//默认是当前日期 -
创建一个指定日期的Calendar对象:
//创建一个代表2009年6月12日的Calendar对象 Calendar c1 = Calendar.getInstance(); c1.set(2009, 6 - 1, 12); -
Calendar类对象字段类型:
常量 描述 Calendar.YEAR 年份 Calendar.MONTH 月份 Calendar.DATE 日期 Calendar.DAY_OF_MONTH 日期,和上面的字段意义完全相同 Calendar.HOUR 12小时制的小时 Calendar.HOUR_OF_DAY 24小时制的小时 Calendar.MINUTE 分钟 Calendar.SECOND 秒 Calendar.DAY_OF_WEEK 星期几 -
类对象信息的设置:
-
Set设置:
-
c1.set(Calendar.DATE,10); //日期设置为10号 -
c1.set(Calendar.YEAR,2008); //年份设置为2008年
-
-
Add设置:
-
c1.add(Calendar.DATE, 10); //日期加上10 -
c1.add(Calendar.DATE, -10); //日期减去10
-
-
-
Calendar类对象信息的获得:
Calendar c1 = Calendar.getInstance(); // 获得年份 int year = c1.get(Calendar.YEAR); // 获得月份 int month = c1.get(Calendar.MONTH) + 1; // 获得日期 int date = c1.get(Calendar.DATE); // 获得小时 int hour = c1.get(Calendar.HOUR_OF_DAY); // 获得分钟 int minute = c1.get(Calendar.MINUTE); // 获得秒 int second = c1.get(Calendar.SECOND); // 获得星期几(注意(这个与Date类是不同的):1代表星期日、2代表星期1、3代表星期二,以此类推) int day = c1.get(Calendar.DAY_OF_WEEK);
1.3.5 GregorianCalendar类
-
实现了公历日历,GregorianCalendar是Calendar类的一个具体实现
-
几个构造方法:
序号 构造函数和说明 1 GregorianCalendar() 在具有默认语言环境的默认时区内使用当前时间构造一个默认的 GregorianCalendar。 2 GregorianCalendar(int year, int month, int date) 在具有默认语言环境的默认时区内构造一个带有给定日期设置的 GregorianCalendar 3 GregorianCalendar(int year, int month, int date, int hour, int minute) 为具有默认语言环境的默认时区构造一个具有给定日期和时间设置的 GregorianCalendar。 4 GregorianCalendar(int year, int month, int date, int hour, int minute, int second) 为具有默认语言环境的默认时区构造一个具有给定日期和时间设置的 GregorianCalendar。 5 GregorianCalendar(Locale aLocale) 在具有给定语言环境的默认时区内构造一个基于当前时间的 GregorianCalendar。 6 GregorianCalendar(TimeZone zone) 在具有默认语言环境的给定时区内构造一个基于当前时间的 GregorianCalendar。 7 GregorianCalendar(TimeZone zone, Locale aLocale) 在具有给定语言环境的给定时区内构造一个基于当前时间的 GregorianCalendar。 -
一些方法列表:
序号 方法和说明 1 void add(int field, int amount) 根据日历规则,将指定的(有符号的)时间量添加到给定的日历字段中。 2 protected void computeFields() 转换UTC毫秒值为时间域值 3 protected void computeTime() 覆盖Calendar ,转换时间域值为UTC毫秒值 4 boolean equals(Object obj) 比较此 GregorianCalendar 与指定的 Object。 5 int get(int field) 获取指定字段的时间值 6 int getActualMaximum(int field) 返回当前日期,给定字段的最大值 7 int getActualMinimum(int field) 返回当前日期,给定字段的最小值 8 int getGreatestMinimum(int field) 返回此 GregorianCalendar 实例给定日历字段的最高的最小值。 9 Date getGregorianChange() 获得格里高利历的更改日期。 10 int getLeastMaximum(int field) 返回此 GregorianCalendar 实例给定日历字段的最低的最大值 11 int getMaximum(int field) 返回此 GregorianCalendar 实例的给定日历字段的最大值。 12 Date getTime() 获取日历当前时间。 13 long getTimeInMillis() 获取用长整型表示的日历的当前时间 14 TimeZone getTimeZone() 获取时区。 15 int getMinimum(int field) 返回给定字段的最小值。 16 int hashCode() 重写hashCode. 17 boolean isLeapYear(int year) 确定给定的年份是否为闰年。 18 void roll(int field, boolean up) 在给定的时间字段上添加或减去(上/下)单个时间单元,不更改更大的字段。 19 void set(int field, int value) 用给定的值设置时间字段。 20 void set(int year, int month, int date) 设置年、月、日的值。 21 void set(int year, int month, int date, int hour, int minute) 设置年、月、日、小时、分钟的值。 22 void set(int year, int month, int date, int hour, int minute, int second) 设置年、月、日、小时、分钟、秒的值。 23 void setGregorianChange(Date date) 设置 GregorianCalendar 的更改日期。 24 void setTime(Date date) 用给定的日期设置Calendar的当前时间。 25 void setTimeInMillis(long millis) 用给定的long型毫秒数设置Calendar的当前时间。 26 void setTimeZone(TimeZone value) 用给定时区值设置当前时区。 27 String toString() 返回代表日历的字符串。
1.4 IO流
- Java.io 包几乎包含了所有操作输入、输出需要的类
- 一个流可以理解为一个数据的序列。输入流表示从一个源读取数据,输出流表示向一个目标写数据
1.4.1 读取控制台输入
-
Java 的控制台输入由 System.in 完成
-
把 System.in 包装在一个 BufferedReader 对象中来创建一个字符流:
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); -
BufferedReader 对象创建后,我们便可以使用 read() 方法从控制台读取一个字符,或者用 readLine() 方法读取一个字符串
1.4.2 从控制台读取多字符输入
-
read()语法原型:
int read( ) throws IOException -
每次调用 read() 方法,它从输入流读取一个字符并把该字符作为整数值返回。 当流结束的时候返回 -1,该方法抛出 IOException
-
用 read() 方法从控制台不断读取字符直到用户输入
q://使用 BufferedReader 在控制台读取字符 import java.io.*; public class BRRead { public static void main(String[] args) throws IOException { char c; // 使用 System.in 创建 BufferedReader BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("输入字符, 按下 'q' 键退出。"); // 读取字符 do { c = (char) br.read(); System.out.println(c); } while (c != 'q'); } }
1.4.3 从控制台读取字符串
-
readline()语法原型:
String readLine( ) throws IOException -
用readline()方法读取和显示字符行直到你输入了单词
end://使用 BufferedReader 在控制台读取字符 import java.io.*; public class BRReadLines { public static void main(String[] args) throws IOException { // 使用 System.in 创建 BufferedReader BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str; System.out.println("Enter lines of text."); System.out.println("Enter 'end' to quit."); do { str = br.readLine(); System.out.println(str); } while (!str.equals("end")); } }
1.4.4 Scanner类
-
java.util.Scanner 是 Java5 的新特征,可以通过 Scanner 类来获取用户的输入
-
基本语法:
Scanner s = new Scanner(System.in); -
通过 Scanner 类的 next() 与 nextLine() 方法获取输入的字符串:
import java.util.Scanner; public class ScannerDemo1 { public static void main(String[] args) { Scanner scan = new Scanner(System.in); // 从键盘接收数据 // next方式接收字符串 System.out.println("next方式接收:"); // 判断是否还有输入(使用hasNext和next方法) if (scan.hasNext()) { String str1 = scan.next(); System.out.println("输入的数据为:" + str1); } scan.close(); } }import java.util.Scanner; public class ScannerDemo2 { public static void main(String[] args) { Scanner scan = new Scanner(System.in); // 从键盘接收数据 // nextLine方式接收字符串 System.out.println("nextLine方式接收:"); // 判断是否还有输入(使用hasNextLine和nextLine方法) if (scan.hasNextLine()) { String str2 = scan.nextLine(); System.out.println("输入的数据为:" + str2); } scan.close(); } } -
next() 与 nextLine() 区别:
-
next():
- 一定要读取到有效字符后才可以结束输入
- 对输入有效字符之前遇到的空白,next() 方法会自动将其去掉
- 只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符
- 不能得到带有空格的字符串
-
nextLine():
- 以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符
- 可以获得空白
-
-
其余方法(hasNextXxx()、nextXxx())
import java.util.Scanner; class RunoobTest { public static void main(String[] args) { System.out.println("请输入数字:"); Scanner scan = new Scanner(System.in); double sum = 0; int m = 0; while (scan.hasNextDouble()) { double x = scan.nextDouble(); m = m + 1; sum = sum + x; } System.out.println(m + "个数的和为" + sum); System.out.println(m + "个数的平均值是" + (sum / m)); scan.close(); } }$ javac ScannerDemo.java $ java ScannerDemo 请输入数字: 12 23 15 21.4 end 4个数的和为71.4 4个数的平均值是17.85
1.4.5 控制台输出
-
控制台的输出由 print( ) 和 println() 完成。这些方法都由类 PrintStream 定义,System.out 是该类对象的一个引用
-
PrintStream 继承了 OutputStream类,并且实现了方法 write(),write() 也可以用来往控制台写操作
-
write() 的最简单格式如下所示:
void write(int byteval)import java.io.*; //演示 System.out.write(). public class WriteDemo { public static void main(String[] args) { int b; b = 'A'; System.out.write(b); System.out.write('\n'); } }
1.4.6 FileInputStream和FileOutputStream
FileInputStream:
-
该流用于从文件读取数据,它的对象可以用关键字 new 来创建
-
使用字符串类型的文件名来创建一个输入流对象来读取文件:
InputStream f = new FileInputStream("C:/java/hello"); -
也可以使用一个文件对象来创建一个输入流对象来读取文件:
File f = new File("C:/java/hello"); InputStream in = new FileInputStream(f); -
序号 方法及描述 1 public void close() throws IOException{} 关闭此文件输入流并释放与此流有关的所有系统资源。抛出IOException异常。 2 protected void finalize()throws IOException {} 这个方法清除与该文件的连接。确保在不再引用文件输入流时调用其 close 方法。抛出IOException异常。 3 public int read(int r)throws IOException{} 这个方法从 InputStream 对象读取指定字节的数据。返回为整数值。返回下一字节数据,如果已经到结尾则返回-1。 4 public int read(byte[] r) throws IOException{} 这个方法从输入流读取r.length长度的字节。返回读取的字节数。如果是文件结尾则返回-1。 5 public int available() throws IOException{} 返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取的字节数。返回一个整数值。
FileOutputStream:
-
该流用来创建一个文件并向文件中写数据
-
该流在打开文件进行输出前,目标文件不存在,那么该流会创建该文件
-
OutputStream f = new FileOutputStream("C:/java/hello") -
File f = new File("C:/java/hello"); OutputStream fOut = new FileOutputStream(f); -
序号 方法及描述 1 public void close() throws IOException{} 关闭此文件输入流并释放与此流有关的所有系统资源。抛出IOException异常。 2 protected void finalize()throws IOException {} 这个方法清除与该文件的连接。确保在不再引用文件输入流时调用其 close 方法。抛出IOException异常。 3 public void write(int w)throws IOException{} 这个方法把指定的字节写到输出流中。 4 public void write(byte[] w) 把指定数组中w.length长度的字节写到OutputStream中。
1.4.7 文件和I/O
-
创建文件夹:
- mkdir( )方法创建一个文件夹,成功则返回true,失败则返回false。失败表明File对象指定的路径已经存在,或者由于整个路径还不存在,该文件夹不能被创建。
- mkdirs()方法创建一个文件夹和它的所有父文件夹。
//创建目录 "/tmp/user/java/bin" import java.io.File; public class CreateDir { public static void main(String[] args) { String dirname = "/tmp/user/java/bin"; File d = new File(dirname); // 现在创建目录 d.mkdirs(); } } -
读取目录:
- 一个目录其实就是一个 File 对象,它包含其他文件和文件夹
- 对一个文件夹对象调用 isDirectory() 方法会返回 true
- 通过调用该对象上的 list() 方法,来提取它包含的文件和文件夹的列表
//使用 list() 方法来检查一个文件夹中包含的内容 import java.io.File; public class DirList { public static void main(String args[]) { String dirname = "/tmp"; File f1 = new File(dirname); if (f1.isDirectory()) { System.out.println("目录 " + dirname); String s[] = f1.list(); for (int i = 0; i < s.length; i++) { File f = new File(dirname + "/" + s[i]); if (f.isDirectory()) { System.out.println(s[i] + " 是一个目录"); } else { System.out.println(s[i] + " 是一个文件"); } } } else { System.out.println(dirname + " 不是一个目录"); } } }目录 /tmp bin 是一个目录 lib 是一个目录 demo 是一个目录 test.txt 是一个文件 README 是一个文件 index.html 是一个文件 include 是一个目录 -
删除目录或文件:
- 删除文件可以使用 java.io.File.delete() 方法
/tmp/java/ |-- 1.log |-- testimport java.io.File; public class DeleteFileDemo { public static void main(String[] args) { // 这里修改为自己的测试目录 File folder = new File("/tmp/java/"); deleteFolder(folder); } // 删除文件及目录 public static void deleteFolder(File folder) { File[] files = folder.listFiles(); if (files != null) { for (File f : files) { if (f.isDirectory()) { deleteFolder(f); } else { f.delete(); } } } folder.delete(); } }
1.4.8 转义序列
| 转义序列 | 描述 |
|---|---|
| \t | 在文中该处插入一个tab键 |
| \b | 在文中该处插入一个后退键 |
| \n | 在文中该处换行 |
| \r | 在文中该处插入回车 |
| \f | 在文中该处插入换页符 |
| ' | 在文中该处插入单引号 |
| " | 在文中该处插入双引号 |
| \ | 在文中该处插入反斜杠 |
2.Java面向对象
2.1 对象和类
2.1.1 类的定义实例以及变量类型
public class Dog {
//成员变量:定义在类中,方法体之外的变量,在创建对象的时候实例化。
String breed;
int size;
String colour;
int age;
//类变量:在成员变量基础上,声明为 static 类型。
static ear;
/**
* 构造方法:一个类可以有多个构造方法
*/
void Dog() {
}
void Dog(int init_age) {
//这个构造函数仅有一个参数:init_age
}
void Dog(int init_age,int init_size) {
//这个构造函数有两个参数:init_age,init_size
}
void eat() {
//局部变量:在方法、构造方法或者语句块中定义的变量。
//变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
int eat_num;
}
void run() {
}
void sleep(){
}
void name(){
}
}
2.1.2 构造函数
- 如果没有显式地为类定义构造方法,Java 编译器将会为该类提供一个默认构造方法。
- 一个类可以有多个构造方法
2.1.3 创建对象
在Java中,使用关键字 new 来创建一个新的对象。
- 声明:声明一个对象,包括对象名称和对象类型。
- 实例化:使用关键字 new 来创建一个对象。
- 初始化:使用 new 创建对象时,会调用构造方法初始化对象。
2.1.4 访问实例变量和方法
同C++
2.2 继承
class 父类 {
}
class 子类 extends 父类 {
}

- Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性
- 继承可以使用 extends 和 implements 这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承object(这个类在 java.lang 包中,所以不需要 import)祖先类
2.2.1 extends关键字
类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类
public class Animal {
private String name;
private int id;
public Animal(String myName, int myid) {
//初始化属性值
}
public void eat() { //吃东西方法的具体实现 }
public void sleep() { //睡觉方法的具体实现 }
}
public class Penguin extends Animal{
}
2.2.2 implements关键字
可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)
public interface A {
public void eat();
public void sleep();
}
public interface B {
public void show();
}
public class C implements A,B {
}
2.2.3 super 与 this 关键字
- super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类
- this关键字:指向自己的引用
class Animal {
void eat() {
System.out.println("animal : eat");
}
}
class Dog extends Animal {
void eat() {
System.out.println("dog : eat");
}
void eatTest() {
this.eat(); // this 调用自己的方法
super.eat(); // super 调用父类方法
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Animal();
a.eat();
Dog d = new Dog();
d.eatTest();
}
}
2.2.4 构造函数/构造器
- 子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表
- 如果父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器
class SuperClass {
private int n;
SuperClass(){
System.out.println("SuperClass()");
}
SuperClass(int n) {
System.out.println("SuperClass(int n)");
this.n = n;
}
}
// SubClass 类继承
class SubClass extends SuperClass{
private int n;
SubClass(){ // 自动调用父类的无参数构造器
System.out.println("SubClass");
}
public SubClass(int n){
super(300); // 调用父类中带有参数的构造器
System.out.println("SubClass(int n):"+n);
this.n = n;
}
}
// SubClass2 类继承
class SubClass2 extends SuperClass{
private int n;
SubClass2(){
super(300); // 调用父类中带有参数的构造器
System.out.println("SubClass2");
}
public SubClass2(int n){ // 自动调用父类的无参数构造器
System.out.println("SubClass2(int n):"+n);
this.n = n;
}
}
public class TestSuperSub{
public static void main (String args[]){
System.out.println("------SubClass 类继承------");
SubClass sc1 = new SubClass();
SubClass sc2 = new SubClass(100);
System.out.println("------SubClass2 类继承------");
SubClass2 sc3 = new SubClass2();
SubClass2 sc4 = new SubClass2(200);
}
}
/**输出结果
------SubClass 类继承------
SuperClass()
SubClass
SuperClass(int n)
SubClass(int n):100
------SubClass2 类继承------
SuperClass(int n)
SubClass2
SuperClass()
SubClass2(int n):200
**/
2.3 重写与重载
2.3.1 重写
class Animal{
public void move(){
System.out.println("动物可以移动");
}
}
class Dog extends Animal{
public void move(){
System.out.println("狗可以跑和走");
}
public void bark(){
System.out.println("狗可以吠叫");
}
}
public class TestDog{
public static void main(String args[]){
Animal a = new Animal(); // Animal 对象
Animal b = new Dog(); // Dog 对象
a.move();// 执行 Animal 类的方法
b.move();//执行 Dog 类的方法
b.bark();
}
}
/**输出结果---因为b的引用类型Animal没有bark方法
TestDog.java:30: cannot find symbol
symbol : method bark()
location: class Animal
b.bark();
^
**/
- 参数列表与被重写方法的参数列表必须完全相同
- 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected
- 声明为 final 的方法不能被重写
- 声明为 static 的方法不能被重写,但是能够被再次声明
- 构造方法不能被重写
- 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法
- 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法
- 当需要在子类中调用父类的被重写方法时,要使用 super 关键字
class Animal{
public void move(){
System.out.println("动物可以移动");
}
}
class Dog extends Animal{
public void move(){
super.move(); // 应用super类的方法
System.out.println("狗可以跑和走");
}
}
public class TestDog{
public static void main(String args[]){
Animal b = new Dog(); // Dog 对象
b.move(); //执行 Dog类的方法
}
}
2.3.2 重载
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同,最常用的地方就是构造器的重载
-
被重载的方法必须改变参数列表(参数个数或类型不一样)
-
可以改变返回类型
-
可以改变访问修饰符
-
可以声明新的或更广的检查异常
-
能够在同一个类中或者在一个子类中被重载
public class Overloading { public int test(){ System.out.println("test1"); return 1; } public void test(int a){ System.out.println("test2"); } //以下两个参数类型顺序不同 public String test(int a,String s){ System.out.println("test3"); return "returntest3"; } public String test(String s,int a){ System.out.println("test4"); return "returntest4"; } public static void main(String[] args){ Overloading o = new Overloading(); System.out.println(o.test()); o.test(1); System.out.println(o.test(1,"test3")); System.out.println(o.test("test4",1)); } }
| 区别点 | 重载方法 | 重写方法 |
|---|---|---|
| 参数列表 | 必须修改 | 一定不能修改 |
| 返回类型 | 可以修改 | 一定不能修改 |
| 异常 | 可以修改 | 可以减少或删除,一定不能抛出新的或者更广的异常 |
| 访问 | 可以修改 | 一定不能做更严格的限制(可以降低限制) |
2.4 多态
2.4.1 虚函数
Java 中其实没有虚函数的概念,它的普通函数就相当于 C++ 的虚函数,动态绑定是Java的默认行为。如果 Java 中不希望某个函数具有虚函数特性,可以加上 final 关键字变成非虚函数
2.4.2 实现方法(重写、接口、抽象类和抽象方法)
-
重写
- 要想调用父类中被重写的方法,则必须使用关键字 super
- 举例:
//实例化一个Salary对象:使用Employee引用e Employee e = new Salary("员工 B", "上海", 2, 2400.00); -
接口
- java中的接口类似于生活中的接口,就是一些方法特征的集合,但没有方法的实现
-
抽象
2.5 抽象
- 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类
2.5.1 抽象类
- 在 Java 语言中使用 abstract class 来定义抽象类
- 抽象类不能实例化对象,抽象类被继承才能被使用(通常在设计阶段决定要不要设计抽象类)
2.5.2 继承抽象类
- 一个类只能继承一个抽象类,而一个类却可以实现多个接口
- 实例化继承抽象类对象,该对象将从抽象类继承所有成员方法
2.5.3 抽象方法
- 特别的成员方法,该方法的具体实现由它的子类确定
- abstract 关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体
- 抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号
- 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法
声明抽象方法会造成以下两个结果:
- 如果一个类包含抽象方法,那么该类必须是抽象类。
- 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。
//Employee.java
public abstract class Employee
{
private String name;
private String address;
private int number;
public abstract double computePay();
//其余代码
}
//Salary.java
public class Salary extends Employee
{
private double salary; // Annual salary
public double computePay()
{
System.out.println("Computing salary pay for " + getName());
return salary/52;
}
//其余代码
}
2.6 封装
封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方式,防止该类代码和数据被外部类定义的代码随机访问。
-
访问该类的代码和数据,必须通过严格的接口控制
-
封装的优点:
- 良好的封装能够减少耦合
- 类内部的结构可以自由修改
- 对成员变量进行更精确的控制
- 隐藏信息,实现细节
-
封装步骤:
- 修改属性的可见性来限制对属性的访问(一般限制为private)
- 对每个值属性提供对外的公共方法访问,也就是创建一对赋取值方法,用于对私有属性的访问,这些方法被称为getter和setter方法
public class Person{ private String name; private int age; public int getAge(){ return age; } public String getName(){ return name; } public void setAge(int age){ this.age = age; } public void setName(String name){ this.name = name; } } // this 关键字是为了解决实例变量(private String name)和局部变量(setName(String name)中的name变量)之间发生的同名的冲突
2.7 接口
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明
- 接口并不是类,编写接口的方式和类很相似;类描述对象的属性和方法。接口则包含类要实现的方法
- 接口无法被实例化,但是可以被实现,即一个类实现接口内所描述的所有方法,否则必须声明为抽象类
- 接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象
- 接口没有构造方法
- 接口不能包含成员变量,除了 static 和 final 变量
- 接口不是被类继承了,而是要被类实现
- 接口支持多继承
- 接口中的方法会被隐式的指定为 public abstract(隐式抽象)、接口中的变量会被隐式的指定为 public static final 变量
2.6.1 接口的声明
接口的声明语法格式如下:
[可见度] interface 接口名称 [extends 其他的接口名] {
// 声明变量
// 抽象方法
}
简单例子:
/* 文件名 : NameOfInterface.java */
import java.lang.*;
//引入包
public interface NameOfInterface
{
//任何类型 final, static 字段
//抽象方法
}
/* 文件名 : Animal.java */
interface Animal {
public void eat();
public void travel();
}
2.6.2 接口的实现
类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面:
...implements 接口名称[, 其他接口名称, 其他接口名称..., ...] ...
/* 文件名 : MammalInt.java */
public class MammalInt implements Animal{
public void eat(){
System.out.println("Mammal eats");
}
public void travel(){
System.out.println("Mammal travels");
}
public int noOfLegs(){
return 0;
}
public static void main(String args[]){
MammalInt m = new MammalInt();
m.eat();
m.travel();
}
}
2.6.3 接口的继承
- 接口单继承
接口的继承使用extends关键字,子接口继承父接口的方法:
// 文件名: Sports.java
public interface Sports
{
public void setHomeTeam(String name);
public void setVisitingTeam(String name);
}
// 文件名: Football.java
public interface Football extends Sports
{
public void homeTeamScored(int points);
public void visitingTeamScored(int points);
public void endOfQuarter(int quarter);
}//实现Football接口的类需要实现五个方法,其中两个来自于Sports接口
// 文件名: Hockey.java
public interface Hockey extends Sports
{
public void homeGoalScored();
public void visitingGoalScored();
public void endOfPeriod(int period);
public void overtimePeriod(int ot);
}//实现Hockey接口的类需要实现六个方法,其中两个来自于Sports接口
- 接口多继承
在接口的多继承中extends关键字只需要使用一次,在其后跟着继承接口:
public interface Hockey extends Sports, Event
2.6.4 标记接口
最常用的继承接口是没有包含任何方法的接口,即标记接口
-
标记接口没有任何方法和属性的接口,仅仅表明它的类属于一个特定的类型,供其他代码来测试允许做一些事情
-
简单形象的说就是给某个对象打个标(盖个戳),使对象拥有某个或某些特权
-
标记接口主要用于以下两种目的:
-
建立一个公共的父接口:
正如EventListener接口,这是由几十个其他接口扩展的Java API,你可以使用一个标记接口来建立一组接口的父接口。例如:当一个接口继承了EventListener接口,Java虚拟机(JVM)就知道该接口将要被用于一个事件的代理方案
-
向一个类添加数据类型:
这种情况是标记接口最初的目的,实现标记接口的类不需要定义任何接口方法(因为标记接口根本就没有方法),但是该类通过多态性变成一个接口类型
-
例如:java.awt.event 包中的 MouseListener 接口继承的 java.util.EventListener 接口定义如下:
package java.util;
public interface EventListener
{}
2.7 枚举
一个例子明白:
enum Color
{
RED, GREEN, BLUE;
}
public class Test
{
// 执行输出结果
public static void main(String[] args)
{
Color c1 = Color.RED;
System.out.println(c1);
}
}
-
每个枚举都是通过 Class 在内部实现的,且所有的枚举值都是 public static final 的
-
以上的枚举类 Color 转化在内部类实现:
class Color
{
public static final Color RED = new Color();
public static final Color BLUE = new Color();
public static final Color GREEN = new Color();
}
2.7.1 枚举的使用
- 可以使用 for 语句来迭代枚举元素:
enum Color
{
RED, GREEN, BLUE;
}
public class MyClass {
public static void main(String[] args) {
for (Color myVar : Color.values()) {
System.out.println(myVar);
}
}
}
- 在switch中使用枚举:
public static void main(String[] args) {
Color myVar = Color.BLUE;
switch(myVar) {
case RED:
System.out.println("红色");
break;
case GREEN:
System.out.println("绿色");
break;
case BLUE:
System.out.println("蓝色");
break;
}
}
-
values(), ordinal() 和 valueOf() 方法:
enum 定义的枚举类默认继承了 java.lang.Enum 类,并实现了 java.lang.Serializable 和 java.lang.Comparable 两个接口。
values(), ordinal() 和 valueOf() 方法位于 java.lang.Enum 类中:
- values(): 返回枚举类中所有的值。
- ordinal():方法可以找到每个枚举常量的索引,就像数组索引一样。
- valueOf():方法返回指定字符串值的枚举常量。
2.7.2 枚举类成员
- 枚举跟普通类一样可以用自己的变量、方法和构造函数,构造函数只能使用 private 访问修饰符,所以外部无法调用
- 枚举既可以包含具体方法,也可以包含抽象方法(枚举类的每个实例都必须实现它)
//构造函数内部调用
enum Color
{
RED, GREEN, BLUE;
// 构造函数
private Color()
{
System.out.println("Constructor called for : " + this.toString());
}
public void colorInfo()
{
System.out.println("Universal Color");
}
}
public class Test
{
// 输出
public static void main(String[] args)
{
Color c1 = Color.RED;
System.out.println(c1);
c1.colorInfo();
}
}
/**执行以上代码输出结果为:
Constructor called for : RED
Constructor called for : GREEN
Constructor called for : BLUE
RED
Universal Color
**/
//每个对象对抽象方法的实现
enum Color{
RED{
public String getColor(){//枚举对象实现抽象方法
return "红色";
}
},
GREEN{
public String getColor(){//枚举对象实现抽象方法
return "绿色";
}
},
BLUE{
public String getColor(){//枚举对象实现抽象方法
return "蓝色";
}
};
public abstract String getColor();//定义抽象方法
}
public class Test{
public static void main(String[] args) {
for (Color c:Color.values()){
System.out.print(c.getColor() + "、");
}
}
}
2.8 包
2.8.1 说明
作用:
- 如同文件夹一样,包也采用了树形目录的存储方式
- 不同的包中的类的名字是可以相同的
- 限定了访问权限,拥有包访问权限的类才能访问某个包中的类
目的:
- 防止命名冲突
- 访问控制
- 提供搜索和定位类(class)、接口、枚举(enumerations)和注释(annotation)
语法格式:
package pkg1[.pkg2[.pkg3…]];
举例:
/**Something.java**/
package net.java.util;
public class Something{
...
}
//路径是 net/java/util/Something.java 这样保存的
Java中常用的包:
- java.lang-打包基础的类
- java.io-包含输入输出功能的函数
2.8.2 创建包
要求:
- 包声明应该在源文件的第一行,每个源文件只能有一个包声明
- 如果一个源文件中没有使用包声明,那么其中的类,函数,枚举,注释等将被放在一个无名的包(unnamed package)中
举例:(animals包)
- 包中加入接口Animals
/* 文件名: Animal.java */
package animals;
interface Animal {
public void eat();
public void travel();
}
- 包中加入接口Animals的实现MammalInt
package animals;
/* 文件名 : MammalInt.java */
public class MammalInt implements Animal{
public void eat(){
System.out.println("Mammal eats");
}
public void travel(){
System.out.println("Mammal travels");
}
public int noOfLegs(){
return 0;
}
public static void main(String args[]){
MammalInt m = new MammalInt();
m.eat();
m.travel();
}
}
- 编译这两个文件,并把他们放在一个叫做animals的子目录中,使用以下命令:
$ mkdir animals
$ cp Animal.class MammalInt.class animals
$ java animals/MammalInt
Mammal eats
Mammal travel
2.8.3 import关键字
说明:
- 使用某一个包的成员,在 Java 程序中明确导入该包
- import 语句应位于 package 语句之后,所有类的定义之前,可以没有,也可以有多条
- 在一个包中,一个类想要使用本包中的另一个类,那么该包名可以省略
语法格式:
import package1[.package2…].(classname|*);
举例:(在同一个包中)
package payroll; //payroll 包已经包含了 Employee 类
public class Boss
{
public void payEmployee(Employee e)
{
e.mailCheck();
}
}
举例:(不在同一个包中)
- 类全名描述:
import payroll; //payroll 包已经包含了 Employee 类
public class Boss
{
public void payEmployee(payroll.Employee e)
{
e.mailCheck();
}
}
- import引入,使用通配符 *****:
import payroll.*; //payroll 包已经包含了 Employee 类
public class Boss
{
public void payEmployee(Employee e)
{
e.mailCheck();
}
}
- import引入指定类:
import payroll.Employee;//payroll 包已经包含了 Employee 类
public class Boss
{
public void payEmployee(Employee e)
{
e.mailCheck();
}
}
2.8.4 package目录结构
类放在包中会有两种主要的结果:
- 包名成为类名的一部分
- 包名必须与相应的字节码所在的目录结构相吻合
一种简单方式:
-
将类、接口等类型的源码放在一个文本中,这个文件的名字就是这个类型的名字,并以.java作为扩展名
// 文件名 : Car.java package vehicle; public class Car { // 类实现 } -
把源文件放在一个目录中,这个目录要对应类所在包的名字
....\vehicle\Car.java -
类名 -> vehicle.Car
-
路径名 -> vehicle\Car.java (在 windows 系统中)
另一种方式:
通常,一个公司使用它互联网域名的颠倒形式来作为它的包名.例如:互联网域名是 runoob.com,所有的包名都以 com.runoob 开头。包名中的每一个部分对应一个子目录
例如:有一个 com.runoob.test 的包,这个包包含一个叫做 Runoob.java 的源文件,那么相应的,应该有如下面的一连串子目录:
....\com\runoob\test\Runoob.java
-
编译的时候,编译器为包中定义的每个类、接口等类型各创建一个不同的输出文件,输出文件的名字就是这个类型的名字,并加上 .class 作为扩展后缀:
// 文件名: Runoob.java package com.runoob.test; public class Runoob { } class Google { } -
用-d选项来编译这个文件:
$javac -d . Runoob.java -
编译结果:
.\com\runoob\test\Runoob.class .\com\runoob\test\Google.class -
可以像下面这样来导入所有 \com\runoob\test\ 中定义的类、接口等:
import com.runoob.test.* -
分开安排源码和类的目录:
<path-one>\sources\com\runoob\test\Runoob.java <path-two>\classes\com\runoob\test\Google.class
用这种方法管理源码和类文件可以让编译器和java 虚拟机(JVM)可以找到你程序中使用的所有类型
2.8.5 设置CLASSPATH系统变量
用下面的命令显示当前的CLASSPATH变量:
- Windows 平台(DOS 命令行下):C:\> set CLASSPATH
- UNIX 平台(Bourne shell 下):# echo $CLASSPATH
删除当前CLASSPATH变量内容:
- Windows 平台(DOS 命令行下):C:> set CLASSPATH=
- UNIX 平台(Bourne shell 下):# unset CLASSPATH; export CLASSPATH
设置CLASSPATH变量:
- Windows 平台(DOS 命令行下): C:> set CLASSPATH=C:\users\jack\java\classes
- UNIX 平台(Bourne shell 下):# CLASSPATH=/home/jack/java/classes; export CLASSPATH
3 异常处理
异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。
异常发生的原因有很多,通常包含以下几大类:
- 用户输入了非法数据
- 要打开的文件不存在
- 网络通信时连接中断,或者JVM内存溢出。
三种异常:
- 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
- 运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
- 错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
所有的异常类是从 java.lang.Exception 类继承的子类,Exception 类是 Throwable 类的子类。除了Exception类外,Throwable还有一个子类Error ,Error 用来指示运行时环境发生的错误。
3.1 内置异常类
3.2 异常方法
| 序号 | 方法及说明 |
|---|---|
| 1 | public String getMessage() 返回关于发生的异常的详细信息。这个消息在Throwable 类的构造函数中初始化了。 |
| 2 | public Throwable getCause() 返回一个 Throwable 对象代表异常原因。 |
| 3 | public String toString() 返回此 Throwable 的简短描述。 |
| 4 | public void printStackTrace() 将此 Throwable 及其回溯打印到标准错误流。。 |
| 5 | public StackTraceElement [] getStackTrace() 返回一个包含堆栈层次的数组。下标为0的元素代表栈顶,最后一个元素代表方法调用堆栈的栈底。 |
| 6 | public Throwable fillInStackTrace() 用当前的调用栈层次填充Throwable 对象栈层次,添加到栈层次任何先前信息中。 |
3.3 捕获异常
- 使用 try 和 catch 关键字可以捕获异常,try/catch 代码块放在异常可能发生的地方,try/catch代码块中的代码称为保护代码
- finally 关键字用来创建在 try 代码块后面执行的代码块,无论是否发生异常,finally 代码块中的代码总会被执行,在 finally 代码块中,可以运行清理类型等收尾善后性质的语句
- 在 try/catch 后面添加 finally 块并非强制性要求的
- try, catch, finally 块之间不能添加任何代码
使用 try/catch ,finally的语法如下:
//可多重捕获(顺序传递)
try{
// 程序代码
}catch(ExceptionName1 e1){
// 程序代码
}catch(ExceptionName2 e2){
// 程序代码
}catch(ExceptionName3 e3){
// 程序代码
}finally{
// 程序代码
}
3.4 throws/throw 关键字
-
如果一个方法没有捕获到一个检查性异常,那么该方法必须使用 throws 关键字来声明
-
throws 关键字放在方法签名的尾部,也可以使用 throw 关键字抛出一个异常,无论它是新实例化的还是刚捕获到的
-
一个方法可以声明抛出多个异常,多个异常之间用逗号隔开
import java.io.*;
public class className
{
public void withdraw(double amount) throws RemoteException,
InsufficientFundsException
{
// Method implementation
throw new RemoteException();
}
//Remainder of class definition
}
3.5 try-with-resources语法
-
try-with-resource语法糖来打开资源,并且可以在语句执行完毕后确保每个资源都被自动关闭 -
try-with-resource语句关闭所有实现 AutoCloseable 接口的资源 -
try-with-resource语句中可以声明多个资源,方法是使用分号;分隔各个资源
import java.io.*;
import java.util.*;
class RunoobTest {
public static void main(String[] args) throws IOException{
try (Scanner scanner = new Scanner(new File("testRead.txt"));
PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
while (scanner.hasNext()) {
writer.print(scanner.nextLine());
}
}
}
}
/**
以上实例使用 Scanner 对象从 testRead.txt 文件中读取一行并将其写入新的 testWrite.txt 文件中。
多个声明资源时,try-with-resources 语句以相反的顺序关闭这些资源。 在本例中,PrintWriter 对象先关闭,然后 Scanner 对象关闭。
**/
3.6 声明自定义异常
- 所有异常都必须是 Throwable 的子类
- 如果希望写一个检查性异常类,则需要继承 Exception 类
- 如果你想写一个运行时异常类,那么需要继承 RuntimeException 类
以下为一个银行账户的模拟,通过银行卡的号码完成识别,可以进行存钱和取钱的操作
// 文件名InsufficientFundsException.java
import java.io.*;
//自定义异常类,继承Exception类
public class InsufficientFundsException extends Exception
{
//此处的amount用来储存当出现异常(取出钱多于余额时)所缺乏的钱
private double amount;
public InsufficientFundsException(double amount)
{
this.amount = amount;
}
public double getAmount()
{
return amount;
}
}
// 文件名称 CheckingAccount.java
import java.io.*;
//此类模拟银行账户
public class CheckingAccount
{
//balance为余额,number为卡号
private double balance;
private int number;
public CheckingAccount(int number)
{
this.number = number;
}
//方法:存钱
public void deposit(double amount)
{
balance += amount;
}
//方法:取钱
public void withdraw(double amount) throws
InsufficientFundsException
{
if(amount <= balance)
{
balance -= amount;
}
else
{
double needs = amount - balance;
//withdraw() 方法抛出一个 InsufficientFundsException 异常
throw new InsufficientFundsException(needs);
}
}
//方法:返回余额
public double getBalance()
{
return balance;
}
//方法:返回卡号
public int getNumber()
{
return number;
}
}
//文件名称 BankDemo.java
public class BankDemo
{
public static void main(String [] args)
{
CheckingAccount c = new CheckingAccount(101);
System.out.println("Depositing $500...");
c.deposit(500.00);
try
{
System.out.println("\nWithdrawing $100...");
c.withdraw(100.00);
System.out.println("\nWithdrawing $600...");
c.withdraw(600.00);
}catch(InsufficientFundsException e)
{
System.out.println("Sorry, but you are short $"
+ e.getAmount());
e.printStackTrace();
}
}
}
Depositing $500...
Withdrawing $100...
Withdrawing $600...
Sorry, but you are short $200.0
InsufficientFundsException
at CheckingAccount.withdraw(CheckingAccount.java:25)
at BankDemo.main(BankDemo.java:13)
3.7 通用异常
在Java中定义了两种类型的异常和错误。
- JVM(Java虚拟机) 异常:由 JVM 抛出的异常或错误。例如:NullPointerException 类,ArrayIndexOutOfBoundsException 类,ClassCastException 类
- 程序级异常:由程序或者API程序抛出的异常。例如 IllegalArgumentException 类,IllegalStateException 类

浙公网安备 33010602011771号