7 一维数组
7.13 命令行参数
main方法和普通方法一样。还可以从命令行传送参数。
java TestMain args0 args1 args2
字符串用空格分隔。如果字符串包含空格,那就必须使用双引号括住。
java TestMain "First num" alpha 53
9 对象和类
9.10 向方法传递对象参数
给方法传递一个对象,是将对象的引用传递给方法。 Java只有一种参数传递方式:值传递 (pass-by-value) 当传递基本数据类型参数时,传递的是实参的值,不会改变原始的值; 当传递的是引用类型参数时,传递的是对象的引用,可能通过该引用改变对象的属性。 引用的传值在语义上最好描述为传共享 (pass-by-sharing),也就是说,在方法中引用的对象和传递的对象是一样的。
9.12 不可变对象和类
可以定义不可变类来产生不可变对象,不可变对象的内容不能被改变。 String类就是不可变的 不可变类必须满足以下要求:
所以数据域都是私有的 没有修改器方法 没有一个返回指向可变数据域的引用的访问器方法:因为通过这个引用,可以改变类的内容。
9.13 变量的作用域
实例变量和静态变量的作用域是整个类,无论变量是在哪里声明的。 类变量只能声明一次,但是在一个方法内不同的非嵌套块中,可以多次声明相同的变量名。 如果一个局部变量和一个类变量具有相同的名字,那么局部变量优先,而同名的类变量将被隐藏。
9.14 this引用
关键字this是指向调用对象本身的引用名。可以用this关键字引用对象的实例成员。 this引用通常是省略掉的。①引用隐藏数据域以及②调用一个重载的构造方法的时候,this引用是必须的。 ①在数据域的set方法中,经常将数据域名用作参数名。隐藏的静态变量可以简单地通过“类名.静态变量”的方式引用。隐藏的实例变量就需要使用关键字this来引用。 ②关键字this可以用于调用同一个类的另一个构造方法。
注意: Java要求在构造方法中,语句this(参数列表)应在任何其他执行语句之前出现。 提示:如果一个类有多个构造方法,最好尽可能使用this(参数列表)实现它们。通常,无参数或参数少的构造方法可以用this(参数列表)调用参数多的构造方法。–简化代码,易于阅读维护。
10 面向对象思考
10.7 将基本数据类型值作为对象
Java为基本类型提供了Boolean、Character、Double、Float、Byte、Short、Integer和Long包装类 将对象转换为基本类型:*Value()
方法 既可以用基本类型值也可以用表示数值的字符串来构造包装类: new Double(5.0) 或 new Double(“5.0”) 包装类没有无参构造方法;所有包装类的实例都是不可变的。 每一个数值包装类都有常量MAX_VALUE
和MIN_VALUE
(对应的基本数据类型的最大和最小值,对Float、Double而言MIN_VALUE
表示float型和double型的最小正值) compareTo()
用于比较两个数值,大于返回1静态方法valueOf(String s)
: 该方法返回一个新对象,并将它初始化为指定字符串表示的值。
Double doubleObject = Double .valueOf("12.4" );
Integer.parseInt(String s): 将字符串转换为一个int值;parseDouble()同。 Integer.parseInt(String s, int radix): 将字符串转换为正确的以10或指定值为基数的数值。每个数值包装类都有两个重载方法。 可以使用format方法将一个十进制数装换为十六进制数:
String .format("%x" , 26 );
10.8 基本类型和包装类型之间的自动转换
基本类型值->包装类对象:装箱boxing;相反:开箱unboxing 自动装箱和自动开箱
10.9 BigInterger和BigDecimal类(java.math)
可以用于表示任意大小和精度的整数或者十进制数。 创建实例:new BigInteger(String)
和 new BigDecimal(String)
add、subtract、multiple、divide、remainder方法用于运算,compareTo方法比较 对BigDecimal对象的精度没有限制。如果divide结果不能终止,会抛出ArithmeticException异常。使用重载divide(BigDecimal d, int scale, int roundingMode)
指定尺度(小数点后最小的整数位数)和舍入方式(如BigDecimal.ROUND_UP
)。 BigInteger.ONE
= new BigInteger("1")
10.10 String类
字符串是对象。
charAt(index) length() substring() indexOf lastIndexOf String类有13个构造方法以及40多个处理字符串的方法。
10.10.1 构造字符串
字符串直接量创建: new String("Good");
用字符数组创建一个字符串:
char [] charArray = {'G' , 'o' , 'o' , 'd' };
String message = new String(charArray);
10.10.2 不可变字符串与限定字符串
限定的字符串:对具有相同字符序列的字符串直接量使用同一个实例
"hello" == "hello"
"hello" == new String ("hello" )
new String ("hello" ) == new String ("hello" )
"hello" . equals (new String ("hello" ))
10.10.3 字符串的替换和分隔
+replace(oldChar: char , newChar: char ): String
+replaceFirst(oldString: String , newString: String ): String
+replaceAll(oldString: String , newString: String ): String
+split(delimiter: String ): String []
10.10.4 依照模式匹配、替换和分隔
regex:
”.*” “\d” “\d{3}” “[$+&]” “[,.;:?]” matches方法 replace方法 split方法
10.10.5 字符串和数组之间的转换
字符串转数组
toCharArray方法 getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin),将下标从srcBegin到srcEnd-1的子串复制到字符数组dst中下标从dstBegin开始的位置。 字符数组转字符串:
构造方法 String(char[]) String.valueOf(char[])
10.10.6 将字符和数值转换为字符串
Double.parseDouble(str)等将字符串转换为数值; 字符串的连接操作将字符或数字转换为字符串 用String.valueOf()重载方法,将字符或数字转换为字符串
10.10.7 格式化字符串
静态format方法: 创建一个格式化的字符串 String.format(format, item1, item2, item3,...)
printf方法用于显示一个格式化的字符串
10.11 StringBuilder和StringBuffer类
可以给一个StringBuilder或StringBuffer中添加、插入或追加新的内容; StringBuffer修改缓冲区的方法是同步的;如果是多任务并发访问,就使用StringBuffer;单任务访问就用StringBuilder。 四个构造方法 +StringBuilder()
+StringBuilder(capacity: int)
+StringBuilder(char[])
+StringBuilder(s: String)
10.11.1 修改StringBuilder中的字符串
追加append:字符数组、字符数组的子数组(offset,len)、基础类型、字符串 插入insert:给出偏移offset(不是index),用光标思维 删除delete(startIndex,endIndex)、deleteCharAt 替换replace(startIndex,endIndex,String) 倒置reverse 设置新字符setCharAt(index,char)
10.11.2 toString、capacity、length、setLength、charAt、substring、trimToSize
字符串长度总是小于或等于构建器的容量;如果有更多的字符添加到字符串构建器,超出构建器容量就用新的数组替换现有数组。新数组的大小为2*(之前数组长度 + 1) 如果容量过大将会浪费内存空间,可以使用trimToSize()将容量降到实际大小。
12 异常处理
12.1 引言
在程序运行过程中,如果JVM检测出一个不可能执行的操作,就会出现运行时错误(runtime error) 在java中,运行时错误会被作为异常抛出,异常就是一种对象,表示阻止正常进行程序执行的错误或者情况。
12.2 异常处理概述
异常是由方法抛出的,方法的调用者可以捕获以及处理该异常。
throw new ArithmeticException("Divisor cannot be zero" );
上面的语句抛出一个异常,异常是由异常类创建的对象。这种情况下,异常类是java.lang.ArithmeticException,构造方法是ArithmeticException(str),str是描述异常的信息。 当异常被抛出时,正常的执行流程被中断。 try块包含了正常情况下执行的代码,异常被catch块所捕获,catch块的代码执行以处理异常。之后,catch块之后的语句被执行。 throw语句 类似于方法的调用,不同于调用方法的是,它调用的是catch块 。从某种意义上讲,catch块就像带参数的方法定义,这些参数匹配抛出的值的类型。但是,它不像方法,在执行完catch块后,程序控制不返回到throw语句;而是执行catch语句块后的下一条语句 。一个异常可能是通过try块中的throw语句 直接抛出,或者调用一个可能会抛出异常的方法 而抛出。 异常处理的优点:由调用者处理异常,而不是被调用的方法。被调用的方法通常不知道在出错的情况下该做什么,这是库方法的一般情况。库方法可以检测出错误,但是只有调用者才知道出现错误时需要做什么。
12.3 异常类型
Throwable类是所有异常类的根类;所有的java异常类都直接或者间接地继承自Throwable。可以通过继承Exception或者Exception的子类来创建自己的异常类。 异常类可以分为三种类型:系统错误、异常和运行时异常
系统错误System error:由java虚拟机抛出的,用error类表示,描述的是内部系统错误。 异常exception:用Exception类表示。描述的是由程序和外部环境所引起的错误,能被程序捕获和处理。 运行时错误runtime exception:用RuntimeException类表示,描述的是程序的设计错误。 RuntimeException、Error以及它们的子类都成为免检异常(unchecked exception) ;所有其他异常都称为必检异常(checked exception) 。参考Unchecked Exceptions — The Controversy
12.4 关于异常处理的更多知识
12.4.1 声明异常
每个方法都必须声明它可能抛出的必检异常的类型,这叫声明异常 。因为任何代码都可能发生系统错误和运行时错误,因此java不要求在方法中显式声明Error和RuntimeException。 声明异常:使用throws关键字
public void myMethod () throws IOException
public void myMethod ()
throws Exception1, Exception2, ..., ExceptionN
如果方法没有在父类中声明异常,那么就不能在子类中对其进行继承来声明异常。
12.4.2 抛出异常
检测到错误的程序可以创建一个合适的异常类型的实例并抛出它。
throw new IllegalArgumentException("Wrong Argument" );
java API中的每个异常类至少有两个构造方法:无参和带描述信息的String参数,可以用getMessage()获取。
12.4.3 捕获异常
try {
statements;
} catch (Exception exVar1) {
handler for exception1;
} catch (Exception exVar2) {
handler for exception2;
} catch (Exception exVar3) {
handler for exception3;
}
如果在执行try块的过程中没有出现异常,则跳过catch子句,不会产生多余开销 如果try块中的某条语句抛出一个异常,java就会跳过try块中剩余的语句,然后查找处理这个异常的代码(异常处理器exception handler):从当前的方法开始,沿着方法调用链,按照异常的反向传播方向找到这个处理器。
如果在调用的方法链中找不到处理器,程序就会终止并且在控制台上打印出错信息。 如果一个catch块可以捕获一个父类的异常对象,它就能捕获那个父类的所有子类的异常对象。 如果父类的catch块出现在子类的catch块之前,就会导致编译错误 java强迫程序员处理必检异常。 对于使用同样的处理代码处理多个异常的情况,可以使用新的JDK7的多捕获特征(multi-catch feature)简化异常的代码编写。
catch (Exception1 | Exception2 | ... | ExceptionK ex) {
// 处理多个异常情况的同样的处理代码
}
12.4.4 从异常中获取信息
java.lang.Throwable类的实例方法获取有关异常的信息 +getMessage(): String +toString(): String +printStackTrace(): void +getStackTrace(): StackTraceElement[]
12.4.5 实例学习:声明、抛出和捕获异常
12.5 finally子句
无论异常是否产生,finally子句总是会被执行的。 三种情况:1)无异常;2)有异常有捕获;3)有异常无捕获 即使在到达finally块之前有一个return语句,finally块还是会执行 使用finally子句时可以省略掉catch块
12.6 何时使用异常