Java语言程序设计(基础篇)- 笔记(持续更新中)

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_VALUEMIN_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); // returns 1A

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" //true 
"hello" == new String("hello") //false
new String("hello") == new String("hello") //false
"hello".equals(new String("hello")) //true

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 何时使用异常

你可能感兴趣的:(java)