Java程序设计Review
文章目录
CH1 概述
java是一个功能强大的程序设计语言,可以用来开发台式计算机、服务器以及移动设备上的应用程序
java语言的特点
- 可靠、安全
- 编译和解释型语言
- 分布式
- 多线程
- 完全面向对象
- 与平台无关性
Java 的版本、API 、JDK、 IDE概念的含义
- Java SE Java标准版
- Java EE Java企业版
- Java ME Java移动版
- JDK
Java Development Toolkit,即Java开发工具包,由一套独立程序构成的集合,每个程序都是从命令行调用的,用于开发和测试Java程序
- IDE
为了快速开发Java程序而提供的集成开发环境,编辑、编译、链接、调试都集成在一个图形用户界面中
安装JDK时对系统环境变量path的设置
- Windows
①甲骨文官网下载JDK,选择对应的版本
②安装好JDK,注意JRE和JDK不能安装在同一文件夹
③此电脑->右键->属性->高级系统设置->高级->环境变量->系统变量->
新建->
变量名:JAVA_HOME
变量值:JDK安装目录
④path->编辑
输入%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin
⑤win+R打开命令行,分别输入Java -version,Javac -version
⑤完成 - MAC OS
①甲骨文官网下载JDK,选择对应的版本
②安装JDK
③打开终端Terminal,进入当前用户主目录,cd ~
④临时授权,sudo su,输入密码
⑤创建并打开.bash_profile文件,touch .bash_profile(如果存在则不必新建)
⑥输入jdk文件路径
exportJAVA_6_HOME=/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home exportJAVA_8_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_51.jdk/Contents/Homeexport JAVA_HOME=$JAVA_8_HOME
保存并退出
⑧读取并执行文件中的命令,source .bash_profile
⑨在Terminal中输入java -version,显示jdk信息,则配置成功
程序的结构
package packagename//包名
public class name{ //作用域 类名
public static void mian(String[] args){ //作用域、静态的主类(入口)
...
}
void function(parameter1,parameter2...){
...
}//无返回的方法
type function(parameter1,parameter2...){
...
return type
}//有返回的方法
public class classname{ //作用域、类名
void classname(){
...
}//无参的构造方法
void classname(p1,p2...){
...
}//有参的构造方法
}
public class classname extends class{ //作用域、类名,继承自class
@Override//重写检测
public type function(p1,p2...){//重写方法,返回类型要一致
//return type
}
}
}
创建、编译和执行java程序的过程
文件后缀名、编译器和运行器名称
- .java Java源文件
- .class Java字节码,由.Java文件编译而来,类似机器指令,在JVM(Java虚拟机)中被执行
- javac.exe
javac.exe是一个包装器,即Java编译器,将源文件编译为字节码JRE环境下是没有的,它实际上是在运行下面的命令
java -classpath C:\j2sdk\lib\tools.jar com.sun.tools.javac.Main
- Java.exe
Java.exe是从命令行运行Java程序,格式为
Java 文件名
,值得一提的是Java.exe和Javaw.exe都可以执行由Javac编译的字节码文件,但Java.exe在命令行中是阻塞的,即没有执行完此程序,程序不会自动停止,需要Control+C终止
import 语句
- 导入程序运行过程中要用到的类文件
单类型导入,例:import java.util.ArrayList;
按需类型导入,例:import java.util.*;
CH2 基本程序设计
变量概念
- 定义:变量用于表示在程序中可能被改变的值
“+”警告中换行原则
从控制台读取输入
实例化Scanner类
使用Scanner类中的Next*()方法
例如:
Scanner input = new Scanner(System.in);
Int a = input.nextInt();
标识符命名规则
标志符命名规则:
- 字母、数字、下划线、$构成的字符序列
- 不能以数字开头
- 不能是保留字
- 不能是true、false、null
- 可以为任意长度
变量声明方法
变量命名规则:数据类型+变量名(=初始值)
赋值语句、常量
赋值语句将一个值指定给一个变量,在Java中,赋值语句可以是一个表达式,操作符是"="
例如:
int a=0;
double b=0.9;
double c=a*b;
数值数据类型 常见数据类型所能表示的数值范围
类型名 | 范围 | 存储大小 |
---|---|---|
byte | -128~127,(-2^7)~ 2^ -1 | 8位带符号数 |
short | -32768~32767,(-2^15)~ 2^15-1 | 16位带符号数 |
int | -2^31 ~2^31-1 | 32位带符号数 |
long | -2^63 ~2^63-1 | 64位带符号数 |
float | – | 32位带符号数,标准IEEE754 |
double | – | 64位带符号数,标准IEEE754 |
数值直接量(int,double)(L,F)
一个直接量是程序中直接出现的常量值
- 整形直接量:int a=1;
- 浮点型直接量:double b=1.0;
- 科学计数法: 0.0123456 = 1.23456 ∗ 1 0 − 2 = 1.23456 E 2 \ 0.0123456=1.23456\ * 10^{-2}=1.23456E2 0.0123456=1.23456 ∗10−2=1.23456E2
操作符优先级
var++、var–;+、-、++var、–var;(type);!;*、/、%;+、-;<、<=、>、>=;==、!=;^;&&;||;=、+=、-=、*=、/=(从左到右,从高到低)
System.currentTimeMillis()
获取自1970年1月1日午夜到现在的毫秒数
简捷赋值运算符、自增自减
+=、-=、*=、/=、%=
自增:
int a=0;
b=a++ //先将a赋值给b,再将a+1,执行完后,a=1,b=0
c=++a //先将a+1,再将a赋值给c,执行完后,a=2,c=2
自减操作类似
数值类型转换
通过显式转换,浮点数可以转换成整数
在一个二元运算中,一个操作数是整数,一个操作数是浮点数,Java自动将结果转换成浮点类型
总是可以将一个数值赋给支持更大数值范围类型的变量,但反过来不行,必须进行类型转换,且必须显式转换
例:
System.out.println((int)1.4)
>>>>1
字符数据类型及其运算,char类型可以转换成任意一种数值类型
例:
int a='a';//a的值是'a'的ASCII值
char b = (char)OXAB0041;//b的值是OXAB0041对应的字符
注意转换时各数据类型的表示范围
CH3 选择
boolean数据类型
boolean数据类型声明一个具有true或者false的变量
比较运算符
Java提供6种关系操作符:<,<=,>->=,==,!=
if语句
结构为:
if(布尔表达式){
语句(组);
}else{
语句(组);
}
布尔操作符
!,&&,||,^
switch语句
结构为:
switch(status){
case 值1:
语句(组)1;
break;
case 值2:
语句(组)2;
break;
...
default:
语句(组)n;
break;
}
要求:
- status必须能计算出一个类型的值,并用括号
- 值1,2必须与status具有相同的数据类型
- 匹配时,执行对应的代码段,直至break
- 不匹配时,执行default(可选)
- break是可选的,执行到时,立即退出swtich
条件表达式
条件表达式基于一个条件计算表达式的值
结构为:布尔表达式?表达式1:表达式2
如果布尔表达式为true,则条件表达式的结果为表达式1,否则为表达式2
格式化控制台输出
例:
System.out.printf("%5d",a)
运算符的优先级
var++、var–;+、-、++var、–var;(type);!;*、/、%;+、-;<、<=、>、>=;==、!=;^;&&;||;=、+=、-=、*=、/=(从左到右,从高到低)
CH4 数学函数、字符和字符串
常见数学函数的含义及用法
- Math
方法(Math.) | 描述 |
---|---|
exp(x) | 返回e的x次方 |
log(x) | 返回x的自然底数 |
log10(x) | 返回x的以10为底的对数 |
pow(a,b) | 返回a的b次方 |
sqrt(x) | 返回x的平方根,x>=0 |
ceil(x) | x向上取整为最接近的整数,作为双精度值返回 |
floor(x) | x向下取整为最接近的整数,作为双精度值返回 |
rint | x取整为最接近的整数,如果距离相等,取偶数(四舍五入) |
round(x) | x是单精度,返回(int)floor(x),双精度返回(float)floor(x) |
sin(x) | 计算sinx,x是一弧度为单位的角度 |
PI | 圆周率π |
random() | 生成大于等于0.0小于1.0的double类型随机数 |
字符数据类型和操作(字符编码、常见转义字符)
字符数据类型表示单个字符,用单引号’'括住
例如:
char letter = 'a';
char numChar = '4';
将字符映射到它对应的二进制形式的过程称为编码
Unicode和ASCII码
Unicode码用以\u开头的4位16进制数表示
ASCII码是表示所有大小写字母、数字、标点符号和控制字符的8位编码表
特殊字符的转义序列
转义序列 | 名称 |
---|---|
\b | 退格键 |
\t | Tab键 |
\n | 换行符 |
\f | 换页符 |
\r | 回车符 |
\\ | 反斜杠 |
\" | 双引号 |
P108表4-6中的方法
即Character类中的方法(静态方法,可以不通过实例化的对象来调用)
方法(Character.) | 描述 |
---|---|
isDigit(ch) | 如果ch是一个数字,返回true |
isLetter(ch) | 如果ch是一个字母,返回true |
isLowerCase(ch) | 如果ch是小写,返回true |
isUpperCase(ch) | 如果ch是大写,返回true |
toLowerCase(ch) | 返回ch的小写形式 |
字符串类型、表4-7中的方法
字符串类型String是一个字符序列,不是基本类型,而是引用类型
例
String a = "hello world";//这里a是一个引用变量,引用一个值
为hello world的对象
String类的简单方法(实例方法,必须通过实例化的String类型的对象来调用)
方法(s.) | 描述 |
---|---|
length() | 返回字符串中的字符数 |
charAt(index) | 返回字符串中指定位置的字符 |
concat(s1) | 返回一个将本字符串和字符串s1连接的字符串 |
toUpperCase() | 返回一个所有字母大写的字符串 |
toLowerCase() | 返回一个所有字母小写的字符串 |
字符串比较
- String对象的比较方法
方法(s.) | 描述 |
---|---|
euqals(s1) | 如果该字符串等于s1,返回true |
equalsIgnoreCase(s1) | 如果该字符串等于s1,返回true,不区分大小写 |
CampareTo(s1) | 返回一个整数,表明该字符串与s1的大小关系 |
CompareToIgnoreCase() | 与上一个一样,但不区分大小写 |
startsWith(prefix) | 如果字符串以特定前缀开头,返回true |
endsWith(prefix) | 如果字符串以特定后缀结束,返回true |
contains(s1) | 如果s1是该字符串的子串,返回true |
CH5 循环
三种循环的异同
- while
while(循环继续条件{
语句(组);
}
- do-while
do{
语句(组);
}while(循环继续条件)
- for
for(初始操作;循环继续条件;每次迭代之后的操作){
语句(组);
}
使用break和continue实现程序控制
关键字break和continue为循环提供了额外的控制
break,在一次循环中立即终止整个循环
continue,跳过本次迭代,进行下一次循环
CH6 方法
方法可以用于定义可重用的代码以组织和简化代码
方法的定义、调用、给方法传参的方法
- 定义方法
修饰符 返回值类型 方法名(参数列表){
//方法体;
}
方法名和参数列表构成方法签名
定义在方法头中的变量叫做形参,调用方法时,向形参传递值的参数叫做实参
方法参数列表需要独立对每个参数的类型进行说明,也可以不含参数
如果返回值类型为void,则可以没有return语句,否则需要return一个与声明类型相同的变量/值
- 调用方法
如果方法返回一个值/对象,就把方法当做一个值/对象处理
如果方法返回void,对方法的调用就必须是一条语句
当程序调用方法时,程序就转移到方法,执行完return语句或执行到表示方法结束的右括号时,将程序控制返回给调用者
参数传递、值传递
- 通过传值进行参数传递
调用方法时通过传值把实参传给形参
实参必须以与方法参数列表中的形参在次序和数量上匹配,在类型上兼容,即不需要显式类型转换
当调用带参数的方法时,实参的值传递给形参,如果实参是一个变量而非直接量,那么把变量的值传递给形参,这个过程称为按值传递
方法的重载
重载方法使得可以用同样的名字来定义不同的方法,只要他们的签名(方法名和参数列表的集合)是不同的
Java编译器根据方法签名决定使用哪个方法
被重载的方法必须具有不同的参数列表,不能基于不同修饰符和返回值类型类重载方法
当编译器不能确定使用哪个方法时,会发生歧义调用,产生一个编译错误
局部变量的作用域
局部变量的作用域从声明变量的地方开始,到包含该变量的块结束为止
CH7&CH8数组
数组一旦被创建,它的大小是固定的
使用数组的步骤
- 声明引用数组变量
- 创建数组
元素类型[] 数组引用变量名; //声明引用数组变量
数组引用变量名 = new 元素类型[数组大小]; //创建数组
或者
元素类型[] 数组引用变量名= new 元素类型[数组大小];
例如:
char[] a = new char[10];
不同于基本数据类型的变量声明,声明一个数组变量并不在内存中给其分配空间(可以看做并不是实例化的过程),只是创建一个对数组的引用位置
初始化数组
- 简捷语法
元素类型[] 数组引用变量名= {值1,值2,...,值n};
例如:
double[] a = {0.2,0.3,...,0.4}
使用数组初始化语法时,可以不用new,但是声明、创建、赋值必须在同一条语句中
访问数组元素
访问数组元素可以通过下标来访问,起始值基于0,结束值是n-1
foreach循环
Java支持一个简便的for循环,称为foreach循环,即不用下标即可遍历整个数组,语法:
for(double e: mylist){
System.out.println(e);
}
数组的一些操作
- 将一个数组内容复制到另一个数组
简单的list1=list2只是将list1的引用复制给list2,两者都指向同一数组的内存空间
方法:
(1)使用循环一一复制;
(2)使用System中的静态方法arraycopy;
(3)使用clone方法
(4)开发和调用具有数组参数和数组返回值的方法
-
数组的查找(线性查找,二分法查找)
- 线性查找
用循环遍历数组下标,并将下标的值与要查找的元素进行比较
- 二分法查找
前提是数组中的元素必须已经排好序
如果关键字小于中间元素,则在前一半中继续查找
如果关键字等于中间元素,查找成功
如果关键字大于中间元素,则在后一半中继续查找 -
数组的排序(选择法、插入法)
选择排序:先找到最小的数,与第一个互换,接下来在剩余的数中找到最小的数,与第二个互换,以此类推
使用Arrays类中的方法
Java.util.Arrays类包含一些使用的方法用于常见的数组操作,比如排序和查找
Arrays类中的方法是静态方法
方法(Arrays.) | 描述 |
---|---|
sort(list) | 对list按照从小到大排序,可以是数字或字符数组 |
binarySearch(list,value) | 使用二分法查找list中值为value的元素 |
equals(list1,list2) | 判断两个数组是否完全相等 |
fill(list,value) | 用value填充list |
声明和创建二维数组
大致过程和一位数组没有太大的区别,访问时按行和列进行访问
CH9&CH10 对象和类
面向对象编程可以有效地帮助开发大规模的软件以及图形用户界面
对象和类的概念
类是对象的模板,体现对象的状态(属性),行为(方法)
例类:
class Students{
private String name; //数据域
private int age;
private long number;
private Char sex;
students(){ //构造方法
}
public int getAge(){ //带返回值方法
return age;
}
public void setAge(newNumber){ //不带返回值方法
age=newNumber;
}
}
定义和创建类的对象
类是对象的定义,对象从类创建
一般的创建方法:类名 对象名 = new 类名(可选数据域参数);
构造方法的使用和特点
使用构造方法创建对象,构造方法在使用new操作符时被调用
三个特性:
- 构造方法必须具有与所在类相同的名字
- 没有返回值类型
- 在new时被调用,作用是初始化
注意:在创建对象时,将对象的引用赋值给变量,变量可以引用该类的一个实例
java.util.Date
获取当前时间,用除法、求余分解出当前的秒数,分钟数和小时数
Date类结构,其中方法是静态的
java.util.Date
+Date()
+Date(elapseTime: long)
+toString()
+getTime()
+setTime()
java.util.Random
产生一个随机的int,long,double,float和boolean类型的值
Random类结构,其中方法是实例方法
java.util.Random
+Random()
+Random(seed:long)
+nextInt()
+nextInt(n:int)
+nextLong()
...
理解实例变量、静态变量、实例方法、静态方法的区别
- 静态变量也称类变量,被类中所有对象所共享,将值存在一个公共的内存地址,声明时在其前方加上static;
- 实例变量绑定到某个类的特定实例,不能被不同对象所共享;
- 静态方法不需要无需创建类的实例即可调用;
- 实例方法必须实例化某个类的对象,然后通过引用变量进行调用
可见性修饰符
可见性修饰符用于确定一个类以及它的成员可见性
修饰符 | 同一类中 | 同一包内 | 子类中 | 不同包中 |
---|---|---|---|---|
public | ✅ | ✅ | ✅ | ✅ |
protected | ✅ | ✅ | ✅ | ❌ |
default | ✅ | ✅ | ❌ | ❌ |
private | ✅ | ❌ | ❌ | ❌ |
数据域的封装
将数据域设为私有保护数据,并且使得类易于维护
定义get/set方法来在类之外获取/修改类的数据域中的数据
变量的作用域
一个类的实例变量和静态变量称为类变量,局部变量是在方法内部声明并使用的变量,类变量的作用域是整个类,局部变量作用域是在声明的块中
注意:如果一个局部变量和一个类变量具有相同的名字,那么在方法中局部变量优先,并且同名的类变量被隐藏
this引用
关键字this引用对象自身,也可以在构造方法内部用于调用同一个类的其它构造方法
- 使用this引用隐藏的数据域
- 使用this调用构造方法(本类中)
基本类型和包装类型
类的抽象是指将类的实现和使用分开,类的封装是指实现的细枝末节对用户隐藏
基本类型和包装类型的区别
Java的类型分为两部分,一个是基本类型(primitive),如int、double等八种基本数据类型;另一个是引用类型(reference type),如String、List等。而每一个基本类型又各自对应了一个引用类型,称为包装类型(或装箱类型,boxed primitive)装箱基本类型中对应于int 、double、和boolean的是Integer、Double、Boolean
在混合使用基本类型和包装类型时会自动拆箱
BigInteger和BigDecimal类的基本用法
BigInteger和BigDecimal用于表示任意大小和精度的整数或者十进制数
例:
BigInteger a = new BigInteger("123456789098765432");
BigDecimal b =a new BigDecimal("3.14159265716273849");
BigInteger c = a.multipy(a);
...
String类的常用方法
String类对象是不可改变的,字符串一旦创建,内容不可以更改
- 实例方法
方法s. | 描述 |
---|---|
replace(char a, char b) | 用字符a替换字符串中的字符b,返回新串 |
replaceFirst(char a, char b) | 同上,但是只替换第一个匹配的 |
split(char a) | 返回一个字符数组,包含被分隔符分割的字符串子集 |
matches(String a) | 如果a与s匹配,返回true |
equals(String a) | 如果a与s完全相同,返回true |
- 静态方法
方法String. | 描述 |
---|---|
valueOf(char c) | 返回包含字符c的字符串 |
valueOf(char[] c) | 返回包含数组c中字符的字符串 |
valueOf(double c) | 返回c的字符串表示 |
… | … |
format(format, s1,s2…) | 返回一个format格式控制的字符串 |
StringBuilder和StringBuffer类
StringBulider和StringBuffer类与String类相似,但他们是可变的,一般来说,只要使用字符串的地方,都可以用他们代替
- 类结构(以StringBuilder为例,方法为实例方法)
java.long.StringBuilder
+StringBuilder()
+StringBuilder(capacity:int)
+StringBuilder(s:String)
+append(char[])
+append(char[],offset,len)
+append(a:aPrimitiveType)
+append(s:String)
+deleteCharAt(int)
+reverse()
+setChatAt(int)
+toString()
+capacity()
+charAt(int)
...
CH11 继承和多态
继承的概念和定义
继承使得可以定义一个通用的类(父类),之后扩充该类成为一个更加具体的类(子类)
所谓继承是指一个类的定义可以基于另外一个已经存在的类,即子类基于父类,从而实现父类代码的重用,通过继承子类自动拥有了基类的所有属性和方法,也可以增加自己的属性和方法
子类的继承性
- 子类不是父类的子集,通常比父类包含更多信息和方法
- 父类的私有数据域在子类中不可以直接访问,如果父类提供了公共修改器,则可以通过其修改
- 不是所有的is-a关系都适合用继承来建模
- 某些高级语言支持多重继承,但java不允许
super关键字的意义和用法
关键字super指代父类,可以调用父类中的普通方法和构造方法
调用父类构造方法:super();或super(参数);
调用父类方法:super().method();当子类已经继承到父类的方法时,没有必要再加上super,但是某些情况必须加,例如有时方法的重写
注意:要调用父类的构造方法,必须调用super关键字,并且这个调用必须是构造方法的第一条语句
方法的重写
要重写一个方法,需要在子类中使用与父类中对应方法一样的签名及返回值类型,来进行重新定义
- 当实例方法是可访问时,才能被重写
- 静态方法也能被继承,但不能被重写,否则父类中的静态方法将被隐藏,此时可以使用父类名.隐藏的静态方法来调用
Object类和toString、equals方法的含义
Java中所有的类都继承自jav.lang.Object类
如果定义一个类没有说明其继承性,那么默认这个类为Object类
toString()方法的签名是public String toString()
,调用一个对象的toString()方法会返回一个描述该对象的字符串,默认情况下,返回该对象所属类名、@符号、以及该对象十六进制形式的内存地址所组成的字符串
多态
多态意味着父类的变量可以指向子类对象
例:
class num extends Number{ //num类继承自Number
data area;
num(){ //构造方法
}
methods;
}
Number max = new num(); //max是父类的变量,指向子类,这里即体现了多态
Instanof运算符
对象的引用可以类型转换成对另一种对象的引用,这称为类型转换
总是可以讲一个子类的实例转换成为一个父类的变量,称为向上转换,因为子类的实例永远是父类的实例,当把一个父类的实例转换成子类的变量时,必须用(子类名)进行显式转换,为了转换成功,应确保要转换的对象是子类的一个实例
没有一开始就定义为具体的子类,一个好的经验是先实例化父类的变量,因为它可以转换成任意子类的实例
对于基本类型的转换不同于对对象引用进行转换,基本类型转换返回一个新的值,对象引用转换仍然指向同一个对象
protected修饰符的意义和作用
一个类中的受保护成员可以从子类中访问
子类可以增强父类的方法可见性,比如将protected修改成public,但不能削弱
修饰符的可见性在前面已经提到过
final修饰的类
一个被final修饰的类和方法都不能被扩展,被final修饰的数据域是一个常数
注意:只有final可以修饰局部变量,此时局部变量就成了常量
CH12 异常处理和文本I/O
异常类
异常是从方法抛出的,方法的调用者可以捕获以及处理该异常,异常就是从一个异常类创建的对象,异常的根类是java.lang.Throwable
异常类的三种类型
- 系统错误,用Error类表示
Error类的子类 | 可能引起异常的原因 |
---|---|
LinkageError | 两个类具有依赖关系,但在编译前者后,后者进行了修改变得不兼容 |
VirtualMachineError | Java虚拟机崩溃,或者运行所必须的资源已经耗尽 |
- 异常,用Exception类表示
Exception的子类 | 可能引起异常的原因 |
---|---|
ClassNotFoundException | 试图使用一个不存在的类 |
IOException | 同输入/输出相关的操作 |
- 运行时异常,用RuntimeException表示
RuntimeException的子类 | 可能引起异常的原因 |
---|---|
ArithmeticException | 一个数整除以0 |
NullPointerException | 试图通过一个null引用变量访问一个对象 |
IndexOutOfBoundsException | 数组下标超出范围 |
IllegalArgumentException | 传递给方法的参数非法或不合适 |
异常的声明、抛出和捕获
Java的异常处理模型基于三种操作:声明、抛出、捕获
- 声明
Java当前执行的语句必然属于某个方法,每个方法都必须声明它可能抛出的必检异常类型,不要求显式声明免检异常(Error和RuntimeException)
方法:public void mymethod() throws IOException{}
,关键字throws表明mymethod()方法可能会抛出IOException异常,如果可能抛出多个异常,可以在throws后加一个用逗号分隔的异常列表
- 抛出
使用语句
throw new 异常名("提示语句")
在期望的地方抛出异常方便处理
- 捕获
我们可以在try-catch语句中捕获异常并进行处理,例如
try{
语句;
}catch(异常类 变量名){
检测到异常类的异常时执行的语句;
}
异常处理程序的执行流程
1. 如果在执行try块时没有出现异常,则跳过catch子句
2. 如果try块中某条语句抛出一个异常,Java会跳过try块中剩余的语句,开始查找处理这个异常的代码的过程,处理这个异常的代码被称为异常处理器
3. 查找的过程是从第一个到最后一个逐个检查catch块中的异常类实例是否与抛出的异常对应
4. 如果是,则执行对于catch语句块中的代码
5. 如果没有找到,Java会退出这个方法,把异常传递给调用这个方法的方法
6. 继续同样的过程
7. 如果最终没有查找到,程序会自动终止,并在控制台打印异常信息
Finally语句
无论异常是否产生,finally子句总是会被执行
结构:
try{
语句;
}catch(异常类 变量名){
检测到异常类的异常时执行的语句;
}finally{
语句;
}
File类的使用
File类包含了获得一个文件/目录的属性,以及对文件/目录属性进行改名和删除的方法
File类的结构
java.io.File
+File(pathname:String)
+exists():boolean
+canRead():boolean
+canWrite():boolean
...
文件输入输出的基本方法
- 使用Scanner类读取文件数据
例:
import java.util.Scanner;
java.io.File file = new java.io.File(String pathname);
Scanner intput = new Scanner(file);
while(input.hasNext()){
System.out.println(input.next());
...
}
- 使用PrintWriter类向文本文件中写入数据
例:
java.io.File file = new java.io.File(String pathname);
java.io.PrintWriter output = new java.io.PrintWriter output(file);
output.print(String a);
output.println(String b);
output.close();
...
可以使用try-with-resources自动关闭资源
try(声明和创建资源){
使用资源处理文件;
}
从web上读取数据的方法
为了从web上读取一个文件,首先要使用java.net.URL类的构造方法,创建一个URL对象
例:
try{
URL url = new URL(String url)
}catch(MalformedURLException ex){
ex.printStackTrace();
}
注意:http等网络协议是必须的,如果URL字符串出现语法错误,会抛出一个异常,读取数据时,和本地读取的方法一样
CH13 抽象类和接口
抽象类的定义和特点
抽象类不可以用于创建对象,抽象类可以包含抽象方法,这些方法将在子类中被实现
- 定义
抽象类的头部使用abstract修饰,在UML图中,抽象类和抽象方法用斜体表示
- 特点
1. 抽象类和常规类很像,但不能通过new来创建实例
2. 抽象方法只有定义没有实现
3. 抽象类的构造方法定义为protected,因其只被子类调用,创建一个子类时,父类的构造方法被调用,以初始化父类中定义的数据域
4.抽象方法不能包含在非抽象类中
5. 子类可以覆盖父类的方法并将其定义为abstract,很少见
6. 即使子类的父类是具体的,子类也可以是抽象的
7. 不能使用new创建实例,但是可以作为一种数据类型,如Number[] a = new Number[10]
示例学习:抽象的Number类
接口的定义和特点
接口是一种与类相似的结构,只包含常量和方法
- 定义
为了区分接口和类,Java用下列语法来定义接口:
修饰符 interface 接口名{
/*常量声明*/
/*方法签名*/
}
接口的使用(关键字)
接口的实现用到implements关键字,例如:
class chicken extends Animal implements Edible{
//继承自Animal抽象类并实现Edible接口
@Override
public String howToEat(){ //重写Edible的howToEat()方法
return "Chicken: Fry it! "
}
}
抽象类和接口的比较
变量 | 构造方法 | 方法 | |
---|---|---|---|
抽象类 | 无限制 | 子类通过构造方法链调用构造方法,不能通过new实例化 | 无限制 |
接口 | 所有变量必须是public static final | 没有构造方法,不能用new实例化 | 所有方法必须是公共的抽象实例方法 |
另:Java只允许子类继承自唯一的父类,但是子类可以实现多个接口
CH14&15&16 JavaFx基础
使用JavaFx设计GUI的基本流程
1. 搭建舞台 ,通过重写Application类的start方法来实现
2. 设置场景,在start中用new实例化Scene对象
3. 添加面板,在start()中用new实例化Pane或其他面板类对象
4. 添加结点,在start()中用new实例化需要的结点
5. 设置结点参数,设置属性绑定,添加时事件处理等
6. 根据需求将结点添加进指定的面板,面板添加进指定的场景,用stage的setScene()方法设置场景
7. 舞台参数设置,展示舞台
Color、Font、Image、ImageView等基本类的使用
Color类可以用于创建颜色;Font类描述字体名、粗细和大小;Image类表示一个图像;ImageView类可以显示一个图像
实例代码:
Circle c = new Circle(10); //实例化一个圆形对象
Circle.setFill(Color.BLACK); //设置填充为黑色,BLACK是Color类的一个常量,可以直接调用
Lable l1 = new Lable("hello world"); //实例化一个标签对象
l1.setFont(Font.font("Times New Roman",FontWeight.BOLD));
//通过Font类的font方法设置字体样式,这里font()是一个静态方法,可以直接调用
Image p1 = new Image(path/name); //实例化一个Image对象p1,指向路径下的某个文件
ImageView display = new ImageView(p1);//实例化一个ImageView对象,内容是p1
display.setFitHeigth(100);
display.setFitWidth(100);//通过实例方法设置展示的长宽
...
面板的类型和特点
类 | 描述 |
---|---|
Pane | 布局面板的基类,用getChildren()返回面板中中的节点列表 |
StackPane | 节点放置在面板中央,并叠加于其他节点之上 |
FlowPane | 以水平方式一行一行或垂直方式一列一列放置 |
GridPane | 结点放置在一个二维网格的单元中 |
BorderPane | 将结点放置在顶部、底部、左侧、右侧以及中间区域 |
HBox | 结点放置在单行中 |
VBox | 结点放置在单列中 |
常用的形状
类 | 描述 | 构造方法、参数 |
---|---|---|
Text | 文本框 | Text(height,width,“text”) |
Line | 线条 | Line(startX,startY,endX,endY) |
Rectangle | 矩形 | Rectangle(leftopX,leftopY,height,width) |
Circle | 圆形 | Circle(centerX,centerY,r) |
Ellipse | 椭圆 | Ellipse(centerX,centerY,r1,r2) |
Arc | 弧 | Arc(centerX,centerY,r1,r2,startAngle,len) |
Polygon | 多边形(闭合) | Polygon() |
Polyline | 多边形(不闭合) | PolyLine() |
事件驱动编程的概念、事件、事件源
事件驱动编程可以编写代码以处理诸如单击按钮、鼠标移动以及键盘输入之类的事件
事件是从一个事件源上产生的对象,触发一个事件意味着产生一个事件并委派处理器处理该事件
注册处理器及其处理接口P507
处理器是一个对象,他必须通过一个事件源对象进行注册,并且必须是一个恰当事件处理接口的实例
一个事件如果要称为一个源对象上面的事件处理器,必须满足:
1.处理器对象必须是一个对应事件处理接口的实例;
2. 处理器对象必须通过源对象进行注册,注册方法依赖于事件类型
原因是Java采用一个委派模型进行事件处理,一个源对象触发一个事件,然后一个对该事件感兴趣的对象处理它,则必须满足上述条件
实例(单击按钮的事件):
Button btOK = new Button("OK");
btOK.setOnAction(new ClickedButton());
class ClickedButton implements EventHandler<ActionEvent>{
@Override
public void handle(ActionEvent e){
System.out.println("OK button is clicked!");
}
}
Lambda表达式简化事件处理器
- 内部类
内部类又称嵌套类,定义在另一个类的范围内的类,内部类对于定义处理器类非常有用
- 一个内部类可以引用定义在它所在的类中的数据和方法
- 一个内部类可以使用可见性修饰符所定义
- 内部类可以被定义为static,此时可以使用外部类的名字所访问,但它本身不能访问外部类中的非静态成员
- 匿名内部类处理器
一个匿名内部类是一个没有名字的内部类,它将进一步实现定义一个内部类以及创建一个内部类的实例
- 匿名内部类总是从父类继承或者实现一个接口,但是不能有显式的exrends或implements子句
- 匿名内部类必须实现父类或接口中所有的抽象方法
- 匿名内部类总是使用其父类的无参构造方法创建一个实例
- 匿名内部类被编译成OuterClassName$n.class类
- 如果不使用匿名内部类,那么对每个事件都要添加相应的独立的事件处理器
- 使用lambda表达式简化事件处理
lambda表达式可以用于极大简化事件处理的代码编写
对比:
//匿名内部类事件处理器
btOK.setOnAction(new EventHandler<ActionEvent>(){
@Override
public void handle(ActionEvent e){
语句;
}
});
//lambda表达式
btOK.setOnAction(e->{
语句;
})
一个lambda表达式的基本语法是
(type1 param1, type2 param2,...)->expression
或者
(type1 param1, type2 param2,...)->{statements;}
常见UI组件及其基本用法
略,复习下14~16章节的实验即可
@Nickname4th 2018.12.13