目录
一. java三大版本
二. 注释
三. 标识符和关键字
3.1. 标识符
3.2. 关键字
四. 数据类型
4.1. 数据类型
4.2. 数据类型扩展
4.2.1. 整数扩展
4.2.2. 浮点数扩展
4.2.3. 字符扩展
4.2.4. 转义字符
五. 类型转换
5.1. java数据类型优先级
5.2. 强制类型转换
5.3. 自动类型转换
六. 变量、常量和作用域
6.1. 变量
6.2. 变量作用域
6.3. 常量
6.4. 命名规范
七. 运算符
7.1. 算术运算符
7.2. 关系运算符
7.3. 逻辑运算符
7.4. 位运算符
7.5. 条件运算符
7.6. 扩展赋值运算符
7.7. 运算符优先级
八. 包机制
九. JavaDoc生成文档
十. Scanner用户交互
十一. 顺序结构
十二. 选择结构
12.1. if
12.2. switch...case...
十三. 循环结构
13.1. while循环
13.2. do...while循环
13.3. for循环
13.4. 增强型for循环
十四. break & continue & goto
14.1. break
14.2. continue
十五. 方法
15.1. 方法的定义
15.2. 值传递
15.3. 引用传递
15.4. 方法的调用
15.4.1 简单的调用
15.4.2. 静态方法与非静态方法的调用
15.5. 方法的重载
十六. 可变参数(不定项参数)
十七. 递归
十八. 数组
18.1. 数组的定义
18.2. 数组声明创建
18.3. 数组的初始化
18.4. 数组的四个基本特点
18.5. 多维数组
18.6. Arrays类
18.7. 冒泡排序
18.8. 稀疏数组
十九. 三种初始化和内存分析
二十. 面向对象编程
20.1. 面向对象简介
20.1.1 面向过程与面向对象
20.1.2. 什么是面向对象
二十一. 类与对象
21.1. 类与对象
21.2. 构造器
21.3. 封装
21.4. 继承
21.4.1. Object类
21.4.2. super 与 this
21.4.3. 方法重写
21.5. 多态
21.6. instanceof
21.7. 类型转换
二十二. static关键字详解
22.1. 静态变量和静态方法
22.2. 静态代码块
22.3. 静态导入包
二十三. 抽象类
二十四. 接口
二十五. 内部类
二十六. 异常
26.1. 异常的种类
26.2. 异常的体系
26.2.1 Error
26.2.2. Exception
26.3. 异常处理机制
26.4. 自定义异常
一. java三大版本
JavaSE 标准版(桌面程序,控制台开发...)
JavaME 嵌入式开发(手机,小家电...)
JavaEE 企业级开发(web端,服务器开发...)
二. 注释
// 单行注释
/*
*多行注释
*多行注释
*/
/**
*文档注释
*文档注释
*/
三. 标识符和关键字
3.1. 标识符
3.2. 关键字
abstract | assert | boolean | break | byte |
---|
catch | char | class | const | continue | do | double | else | enum | extends | finally | float | for | goto | if | import | instanceof | int | interface | long | new | package | private | protected | public | strictfp | short | static | super | switch | this | throw | throws | transient | try | void | volatile | while | case | default |
?
四. 数据类型
4.1. 数据类型
?
// byte
? ?byte num1 = 10;
// short
? ?short num2 = 20;
// int
? ?int num3 = 30;
// long
? ?long num4 = 30L; // long类型后面要加L
// float
? ?float num5 = 10.0F; // float类型后面要加F
// double
? ?double num6 = 20.0;
// char
? ?char num7 = 'a';
// boolean
boolean num8 = true; // 大小为1位(bit,8位=1字节,即8b=1B)
4.2. 数据类型扩展
4.2.1. 整数扩展
/* 整数扩展
* 进制:二进制(以0b开头) ? 十进制 ? 八进制(以0开头) ? 十六进制(以0x开头)
* */
int num01 = 0b10;
int num02 = 10;
int num03 = 010;
int num04 = 0x10;
?
System.out.println(num01); // 输出结果为2
System.out.println(num02); // 输出结果为10
System.out.println(num03); // 输出结果为8
System.out.println(num04); // 输出结果为16
4.2.2. 浮点数扩展
// 浮点数扩展
float f = 0.1f;
double d = 1 / 10;
System.out.println(f==d); // 输出结果为false(精度丢失)
// 尽量不适用浮点数进行比较(解决方法:使用Bigdecimal'数字工具类')
4.2.3. 字符扩展
// 字符扩展
char c1 = 'A';
char c2 = '好';
?
System.out.println(c1); // 输出结果为A
System.out.println(c2); // 输出结果为好
System.out.println((int)c1);// 输出结果为65
System.out.println((int)c2);// 输出结果为22909
?
/*所有字符本质还是数字
* 编码 Unicode表:65--A ? ? 97--a ? 22909--好
* */
?
// uFFFF Unicode表示
char c3 = '\u0061'; ? ?// 97的十六进制为61
System.out.println(c3);// 输出结果为a
4.2.4. 转义字符
// 转义字符
// 换行符:\n,制表符:\t...
?
System.out.println("hello\nworld");
/*输出结果为
* hello
* world*/
?
System.out.println("hello\tworld");
/*输出结果为
* hello ? world
* */
五. 类型转换
注意:
-
运算中,不同类型的数值,先将转换成为同一类型,再进行运算 -
不能对boolean值进行转换 -
不能把对象类型转换成不相关的类型 -
把容量大的类型转换为容量小的类型时,须使用强制类型转换 -
转换过程中可能导致 内存溢出 或者 损失精度
5.1. java数据类型优先级
由低到高: byte,short,char—> int —> long—> float —> double
5.2. 强制类型转换
(类型)变量名 优先级由高转到低
int i=128;
byte b=(byte) i;
System.out.println(i); ?//输出结果为128
System.out.println(b); ?//输出结果为-128 //内存溢出
?
System.out.println((int)23.86); ?//输出结果为23
System.out.println((int)-43.63f); ?//输出结果为-43 //精度丢失
5.3. 自动类型转换
优先级由低转到高
六. 变量、常量和作用域
6.1. 变量
type varName [= value] [ , varName[=value] ;
// 数据类型 变量名 =值(可以有逗号隔开来声明多个变量)
注意:
6.2. 变量作用域
-
类变量(静态变量)
-
-
从属于类 -
所有方法都能调用静态变量,非静态方法可以调用静态变量、实例变量和本方法的局部变量 public class Variable {
? ?static double var = 1000;
? ?public static void main(String[] args) {
? ? ? ?System.out.println(var); ? ?//输出结果为1000.0
? }
}
-
实例变量
-
-
从属于对象 -
如果不初始化,默认为 0 或 0.0 或 false 或 null public class Variable {
? ?int var01;
? ?String var02;
? ?public static void main(String[] args) {
? ? ? ?Variable variable = new Variable();
? ? ? ?System.out.println(variable.var02); //输出结果为null
? ? ? ?System.out.println(variable.var01); //输出结果为0
? }
? ?public void var(){
? ? ? ?System.out.println(var01); //输出结果为0
? }
}
-
局部变量
-
-
必须声明并且初始化值 -
只能在本方法内使用 public class Variable {
? ?public static void main(String[] args) {
? ? ? ?int var = 1;
? ? ? ?System.out.println(var); ? ?//输出结果为1
? }
}
6.3. 常量
final type varName [= value] [ , varName[=value] ;
// final 数据类型 常量名 =值(可以有逗号隔开来声明多个常量)
注意:
public class Constant {
? ?static final double A=1000;
? ?final static String B="Constant"; //final为修饰符,不区分前后顺序
? ?public static void main(String[] args) {
? ? ? ?final int C=100;
? ? ? ?System.out.println(A); ?//输出结果为1000.0
? ? ? ?System.out.println(B); ?//输出结果为Constant
? ? ? ?System.out.println(C); ?//输出结果为100
? }
}
6.4. 命名规范
七. 运算符
基本运算符
(重点)
(了解)
-
位运算符:& | ^ ~ >> << >>> -
条件运算符:? : -
扩展赋值运算符:+= -= *= /=
7.1. 算术运算符
public class Operator {
? ?public static void main(String[] args) {
? ? ? ?int a=10;
? ? ? ?int b=20;
? ? ? ?System.out.println(a+b); ? ? ? ? ? ?//输出结果为30
? ? ? ?System.out.println(a-b); ? ? ? ? ? ?//输出结果为-10
? ? ? ?System.out.println(a*b); ? ? ? ? ? ?//输出结果为200
? ? ? ?System.out.println(a/(double)b); ? ?//输出结果为0.5
? ? ? ?
? ? ? ?System.out.println("===================================");
? ? ? ?
? ? ? ?System.out.println(b%a); ? ? ? ? ? ?//取余,取模,模运算,输出结果为0
? ? ? ?
? ? ? ?System.out.println("===================================");
? ? ? ?
? ? ? ?System.out.println(a); ?//a=10
? ? ? ?int c=a++;
? ? ? ?/*执行这行代码后,先给c赋值,再自增
? ? ? ? ? ?int c=a++;
? ? ? ? ? ?即
? ? ? ? ? ?int c=a; //c=a=10
? ? ? ? ? ?a++;(a=a+1) //a=11
? ? ? ?*/
? ? ? ?System.out.println(c); ?//c=10
? ? ? ?System.out.println(a); ?//a=11
?
? ? ? ?int d=++a;
? ? ? ?/*执行这行代码前,先自增,再给d赋值
? ? ? ? ? ?int d=++a;
? ? ? ? ? ?等同于
? ? ? ? ? ?++a;(a=a+1) //a=12
? ? ? ? ? ?int d=a; //d=a=12
? ? ? ?*/
? ? ? ?System.out.println(a); ?//a=12
? ? ? ?System.out.println(d); ?//d=12
? ? ? ?
? ? ? ?System.out.println("==================进阶1=================");
? ? ? ?
? ? ? ?System.out.println(a); //a=12
? ? ? ?System.out.println(b); //b=20
? ? ? ?System.out.println(a++ + ++b); //输出结果为33
? ? ? ?/*
? ? ? ?b++;
? ? ? ?a + b; <----输出的结果
? ? ? ?a++;
? ? ? ?*/
? ? ? ?
? ? ? ?System.out.println("==================扩展1--幂运算=================");
? ? ? ?
? ? ? ?// 很多运算,我们会使用一些工具类来操作
? ? ? ?// pow()方法的参数都是double类型的,所以变量只能为double
? ? ? ?double pow=Math.pow(2,3); ? // 2.0^3.0=2.0*2.0*2.0=8.0
? ? ? ?System.out.println(pow); //输出结果为8.0
? ? ? ?
? ? ? ?System.out.println("==================扩展2--字符串连接符=================");
? ? ? ?
? ? ? ?
? }
}
7.2. 关系运算符
public class Operator {
? ?public static void main(String[] args) {
? ? ? ?int a=10;
? ? ? ?int b=20;
? ? ? ?// 关系运算符返回结果为 正确 错误(布尔值)
? ? ? ?System.out.println(a>b); ? ?//输出结果为false
? ? ? ?System.out.println(a<b); ? ?//输出结果为true
? ? ? ?System.out.println(a==b); ? ?//输出结果为false
? ? ? ?System.out.println(a!=b); ? ?//输出结果为true
? }
}
7.3. 逻辑运算符
public class Operator {
? ?public static void main(String[] args) {
? ? ? ?boolean e = true;
? ? ? ?boolean f = false;
? ? ? ?// 与(&&) 或(||) 非(!)
? ? ? ?System.out.println("e && f:"+(e && f)); //逻辑与运算:两个变量都为真才为true
? ? ? ?System.out.println("e || f:"+(e || f)); //逻辑或运算:两个变量有一个为真,则为true
? ? ? ?System.out.println("!(e && f):"+!(e && f)); //如果是真,则为假;反之,则为真
?
? ? ? ?System.out.println("==================扩展1=================");
?
? ? ? ?int g=10;
?
? ? ? ?System.out.println(g<4 && (g++>5)); //false
? ? ? ?System.out.println(g); ? ? ? ? ? ? ?//g=10
?
? ? ? ?System.out.println(g<4 && (++g>5)); //false
? ? ? ?System.out.println(g); ? ? ? ? ? ? ?//g=10
?
? ? ? ?// &&运算中,前一项为false时,则不再继续执行,所以g不变
?
? ? ? ?System.out.println(g>4 && (g++==10));//true(先比较,后自增)
? ? ? ?System.out.println(g); ? ? ? ? ? ? ? //g=11
?
? ? ? ?System.out.println(g>4 && (++g==11));//false(先自增,后比较)
? ? ? ?System.out.println(g); ? ? ? ? ? ? ? //g=12
? }
}
7.4. 位运算符
public class Operator {
? ?public static void main(String[] args) {
? ? ? ?int h=42; ? //(42的二进制数为0010 1010)
? ? ? ?int i=30; ? //(30的二进制数为0001 1110)
? ? ? ?// &按位与运算,实则为二进制数每一位数字(0/1)的比较:同为0,则为0;同为1,则为1;不相同,则为0
? ? ? ?System.out.println(h&i); ? ?//结果为0000 1010[补码],而其原码的十进制数为10,则输出结果为10
? ? ? ?// |按位或运算,实则为二进制数每一位数字(0/1)的比较:同为0,则为0;同为1,则为1;不相同,则为1
? ? ? ?System.out.println(h|i); ? ?//结果为0011 1110[补码],而其原码的十进制数为62,则输出结果为62
? ? ? ?// ^异或运算,实则为二进制数每一位数字(0/1i)的比较:相同,则为0;不相同,则为1
? ? ? ?System.out.println(h^i); ? ?//结果为0011 0100[补码],而其原码的十进制数为52,则输出结果为52
? ? ? ?// ~取反运算,实则为二进制数每一位数字(0/1)的反转:1,则为0;0,则为1
? ? ? ?System.out.println(~h); ? ?//结果为1101 0101[补码],而其原码(1010 1011)的十进制数为-43,则输出结果为-43
?
? ? ? ?// <<左移运算,a<<b --> a*2的b次方
? ? ? ?System.out.println(3<<3); ? //输出结果为24
? ? ? ?// >>右移运算,a>>b --> a/2的b次方
? ? ? ?System.out.println(16>>3); ?//输出结果为2
? }
}
7.5. 条件运算符
public class Operator {
? ?public static void main(String[] args) {
? ? ? ?// x ? y : z
? ? ? ?// 如果x==true,则结果为y,否则结果为z
? ? ? ?int score=70;
? ? ? ?String type = score<60 ? "不及格" : "及格";
? ? ? ?System.out.println(type); //输出结果为 及格
? }
}
7.6. 扩展赋值运算符
public class Operator {
? ?public static void main(String[] args) {
? ? ? ?int a=10;
? ? ? ?int b=20;
? ? ? ?a+=b; //a=a+b;
? ? ? ?a-=b; //a=a-b;
? ? ? ?a*=b; //a=a*b;
? ? ? ?a/=b; //a=a/b;
? }
}
7.7. 运算符优先级
优先级 | 运算符 |
---|
1 | ()、[]、{} | 2 | !、~、++、– | 3 | *、/、% | 4 | +、- | 5 | <<、>>、>>> | 6 | <、<=、>、>=、instanceof | 7 | ==、!= | 8 | & | 9 | ^ | 10 | | | 11 | && | 12 | || | 13 | ?: | 14 | =、+=、-=、*=、/=、&=、|=、^=、~=、?=、?=、>>>= |
八. 包机制
注意:
-
为了更好地组织类,Java提供了包机制,用于区别类名的命名空间
-
包语句的语法格式为:
package pkg1[ . pkg2 [ . pkg3 ...]] ;
-
一般利用公司域名倒置作为包名,如:com.baidu.www -
为了能够使用某一个包的成员,我们需要在Java程序中明确导入该包,使用”import“语句可完成此功能
-
导入包语句的语法格式为:
import package1[ . package2 ...] . (classname / *) ;
九. JavaDoc生成文档
-
JavaDoc命令是用来生成自己API文档的 -
参数信息
-
@author 作者名 -
@version 版本名 -
@since 指明需要最早使用的jdk版本 -
@param 参数名 -
@return 返回值情况 -
@throws 异常抛出情况
方法一:命令行生成
进入命令行界面后 ----> 切换到需要生成文档的目录下输入
javadoc -encoding UTF-8 -charset UTF-8 Doc.java
// javadoc -encoding UTF-8 -charset UTF-8 需要生成API文档的Java文件
方法二:使用IDEA生成
找到Tools(工具) ----> Generate JavaDoc(生成JavaDoc)
?
十. Scanner用户交互
基本语法:
Scanner scanner = new Scanner(System.in);
...
scanner.close(); // 一定要关闭,否则会占用资源
十一. 顺序结构
案例:
public class SequentialStructure {
? ?public static void main(String[] args) {
? ? ? ?System.out.println("hello");
? ? ? ?System.out.println("world");
? }
}
十二. 选择结构
12.1. if
-
if单选择结构
-
语法:
if(布尔表达式){
? ?// 如果布尔表达式为true,将执行的语句
}
-
if双选择结构
-
语法:
if(布尔表达式){
? ?// 如果布尔表达式为true,将执行的语句
}else{
? ?// 如果布尔表达式为false,将执行的语句
}
-
if多选择结构
-
语法:
if(布尔表达式1){
? ?// 如果布尔表达式1为true,将执行的语句
}else if(布尔表达式2){
? ?// 如果布尔表达式2为true,将执行的语句
}else if(布尔表达式3){
? ?// 如果布尔表达式3为true,将执行的语句
}else{
? ?// 如果以上布尔表达式都为false,将执行的语句
}
if语句只有一个else语句,并且else语句只能放在else if语句之后
只要其中一个else if语句的布尔表达式为true,则直接结束,其余的else if语句和else语句都将跳过执行
案例:
int score=78;
if (score>80){
? ?System.out.println("优秀");
}else if(score>60){
? ?System.out.println("合格");
}else {
? ?System.out.println("不合格");
}
// 输出结果为 合格
-
嵌套的if结构
-
语法:
if(布尔表达式1){
? ?// 如果布尔表达式1为true,将执行的语句
? ?if(布尔表达式2){
? ?// 如果布尔表达式2为true,将执行的语句
}
}
12.2. switch...case...
-
switch case多选择结构
-
语法:
switch(expression){
? ?case value1:
? ? ? ?// 语句
? ? ? ?break;// 可选
? ?case value2:
? ? ? ?// 语句
? ? ? ?break;// 可选
? ?default:// 可选
? ? ? ?// 语句
}
switch语句中变量可以是byte、short、int、char、String(JavaSE7开始支持)
case后面只能跟常量
default可以在switch语句的任何位置
切记在case语句中缺少break,一般会出现case穿透现象
switch语句遇见break才结束,否则程序默认执行到末尾结束
案例:
public class SelectedStructure {
? ?public static void main(String[] args) {
? ? ? ?char score='B';
? ? ? ?switch (score){
? ? ? ? ? ?case 'A':
? ? ? ? ? ? ? ?System.out.println("优秀");
? ? ? ? ? ? ? ?break;
? ? ? ? ? ?case 'B':
? ? ? ? ? ? ? ?System.out.println("良好");
? ? ? ? ? ? ? ?//break;
? ? ? ? ? ?case 'C':
? ? ? ? ? ? ? ?System.out.println("还行");
? ? ? ? ? ? ? ?//break;
? ? ? ? ? ?default:
? ? ? ? ? ? ? ?System.out.println("合格");
? ? ? }
? }
}
/* 输出结果为
良好
还行
合格
因为case语句中缺少break,程序默认执行到末尾结束
*/
十三. 循环结构
13.1. while循环
while(布尔表达式){// 判断条件
? ?// 循环体
? ?// 迭代
}
案例:
public class CyclicStructure {
? ?public static void main(String[] args) {
? ? ? ?// 1+2+3+……+100=?
? ? ? ?int i=1;
? ? ? ?int sum=0;
? ? ? ?while (i<=100){
? ? ? ? ? ?sum+=i;
? ? ? ? ? ?i++;
? ? ? }
? ? ? ?System.out.println(sum);
? }
}
// 输出结果为 5050
13.2. do...while循环
do{
? ?// 循环体
? ?// 迭代
}while(布尔表达式);// 判断条件
案例:
public class CyclicStructure {
? ?public static void main(String[] args) {
? ? ? ?// 1+2+3+……+100=?
? ? ? ?int i=1;
? ? ? ?int sum=0;
? ? ? ?do {
? ? ? ? ? ?sum+=i;
? ? ? ? ? ?i++;
? ? ? }while (i<=100);
? ? ? ?System.out.println(sum);
? }
}
// 输出结果为 5050
13.3. for循环
for(初始化条件; 布尔表达式; 迭代){// 判断条件、迭代
? ?// 循环体
}
案例:
public class CyclicStructure {
? ?public static void main(String[] args) {
? ? ? ?// 1+2+3+……+100=?
? ? ? ?for (int i = 1; i <= 100; i++) {
? ? ? ? ? ?sum+=i;
? ? ? }
? ? ? ?System.out.println(sum);
? }
}
// 输出结果为 5050
13.4. 增强型for循环
for(声明语句 : 表达式){
? ?// 循环体
}
案例:
public class CyclicStructure {
? ?public static void main(String[] args) {
? ? ? ?// 遍历数组
? ? ? ?int[] numbers={10,20,30,40,50};
? ? ? ?for (int number : numbers){
? ? ? ? ? ?System.out.println(number);
? ? ? }
? }
}
/* 输出结果为
10
20
30
40
50
*/
十四. break & continue & goto
14.1. break
案例:
public class CyclicStructure {
? ?public static void main(String[] args) {
? ? ? ?int i=0;
? ? ? ?while (i<100){
? ? ? ? ? ?i++;
? ? ? ? ? ?if (i==35){
? ? ? ? ? ? ? ?break;// 当i=35时,直接退出循环
? ? ? ? ? }
? ? ? ? ? ?System.out.println(i);
? ? ? }
? }
}
/* 输出结果为
1
2
3
...
33
34
*/
14.2. continue
案例:
public class CyclicStructure {
? ?public static void main(String[] args) {
? ? ? ?int i=0;
? ? ? ?while (i<20){
? ? ? ? ? ?i++;
? ? ? ? ? ?if (i%5==0){// 当i为5的倍数时,跳过此次循环
? ? ? ? ? ? ? ?System.out.println();
? ? ? ? ? ? ? ?continue;
? ? ? ? ? }
? ? ? ? ? ?System.out.print(i+" ");
? ? ? }
? }
}
/* 输出结果为
? ?1 2 3 4
? ?6 7 8 9
? ?11 12 13 14
? ?16 17 18 19
*/
十五. 方法
什么是方法
-
方法是语句的集合,它们在一起执行一个功能 -
方法解决一类问题的步骤的有序组合 -
方法包含在类或对象中 -
方法在程序中被创建,在其他地方被引用 -
设计原则:
-
命名原则:
15.1. 方法的定义
方法包含一个方法头和一个方法体:
-
方法头
-
方法体:方法体包含具体的语句,定义该方法的功能
修饰符 返回值类型 方法名(参数类型 参数名[,参数类型 参数名[,参数类型 参数名[...]]]){
方法体;
return 返回值;
}
?
或者
?
修饰符 void 方法名(参数类型 参数名[,参数类型 参数名[,参数类型 参数名[...]]]){
方法体;
}
15.2. 值传递
值传递是在调用方法时,将实参复制一份内容副本传递到方法中,这样在函数中对参数进行修改,就不会影响到原来的实参
案例:
public class PassByValue {
? ?public static void main(String[] args) {
? ? ? ?int a=100;
? ? ? ?System.out.println(a); // 输出结果为 100
?
? ? ? ?test(a);
?
? ? ? ?System.out.println(a); // 输出结果为 100
? }
? ?public static void test(int a){
? ? ? ?a=10;
? }
}
15.3. 引用传递
引用传递是在调用方法时,将实参的地址直接传递到函数中。这样在函数中对参数进行的修改,就会影响到实参
public class PassByReference {
? ?public static void main(String[] args) {
? ? ? ?Person person = new Person();
? ? ? ?System.out.println(person.name); // 输出结果为 null
?
? ? ? ?changeName(person);
? ? ? ?System.out.println(person.name); // 输出结果为 hello
?
? }
? ?public static void changeName(Person person){
? ? ? ?person.name="hello";
? }
}
?
class Person { String name=null;}
15.4. 方法的调用
15.4.1 简单的调用
15.4.2. 静态方法与非静态方法的调用
// 不同类
package com.oop;
?
public class Method {
? ?public static void main(String[] args) {
? ? ? ?Student.say(); ? ? ? ? ? ? ? ? ? ? ? ? ?// 静态方法:类名.方法名
? ? ? ?Student student = new Student(); ? ? ? ?// 非静态方法,调用方法一:对象名.方法名
? ? ? ?student.study();
? ? ? ?new Student().study(); ? ? ? ? ? ? ? ? ?// 非静态方法,调用方法二:对象名.方法名
? }
}
?
-------------------------------------------------------------
?
package com.oop;
?
public class Student{
? ?public static void say(){
? ? ? ?System.out.println("学生说");
? }
? ?public void study(){
? ? ? ?System.out.println("学生再学习");
? }
}
须知:静态方法只能调用静态方法和静态变量,而非静态方法不仅可以调用非静态方法和非静态变量,还可以调用静态方法和静态变量
原因: 类的静态方法和静态变量属于类,在类加载时就已经分配好内存,因此,可以通过类名直接访问,而非静态方法和非静态变量属于类的对象,只有在类的对象实例化时,才会分配内存,然后再通过实例化的对象去访问,所以,就会出现当一个类的静态方法去调用非静态方法或非静态变量时,会因为类的非静态方法或非静态变量可能不存在,从而导致出错
案例:
public class MethodDemo03 {
? ?// 都是静态的
? ?public static void a(){ b(); }
? ?public static void b(){ }
?
? ?// 都是非静态的
? ?public void c(){ d(); }
? ?public void d(){ }
?
? ?// 一个静态,被调用的方法为静态
? ?public void e(){ f(); }
? ?public static void f(){ }
?
? ?// 一个静态,调用方法的方法为静态
? ?public static void g(){ h(); } // 此调用为错
? ?public void h(){ }
}
15.5. 方法的重载
案例:
public class Method {
? ?public static void main(String[] args) {
? ? ? ?int a=10;
? ? ? ?double b=20;
? ? ? ?double c=30;
? ? ? ?System.out.println(add(a,b));
? ? ? ?System.out.println(add(b,c));
? ? ? ?System.out.println(add(a,b,c));
? ? ? ?System.out.println(add(b,a));
}
? ?public static double add(int a,double b){
? ? ? ?return a+b;
? }
? ?public static double add(double a,double b){ // 类型不同
? ? ? ?return a+b;
? }
? ?public static double add(int a,double b,double c){ // 个数不同
? ? ? ?return a+b+c;
? }
? ?public static double add(double a,int b){ // 参数排列顺序不同
? ? ? ?return a+b;
? }
}
/* 输出结果为
? ?30.0
? ?50.0
? ?60.0
? ?30.0
*/
十六. 可变参数(不定项参数)
-
JDK1.5开始,Java支持传递同类型的可变参数给一个方法 -
在方法声明中,在指定参数类型后加一个省略号(...) -
一个方法中只能只能一个可变参数,它必须是方法的最后一个参数,任何普通的参数必须在它之前声明
案例:
public class VariableParameters {
? ?public static void main(String[] args) {
? ? ? ?//调用可变参数的方法
? ? ? ?printMax();
? ? ? ?printMax(1,21,25,7,131,13,12);
? ? ? ?printMax(new double[]{21,12,32,4,5});
? }
? ?public static void printMax(double... numbers){
? ? ? ?if (numbers.length==0){
? ? ? ? ? ?System.out.println("无数字");
? ? ? ? ? ?return;
? ? ? }
? ? ? ?double temp=numbers[0];
?
? ? ? ?// 比较
? ? ? ?for (int i = 1; i < numbers.length; i++) {
? ? ? ? ? ?if (numbers[i]>temp){
? ? ? ? ? ? ? ?temp=numbers[i];
? ? ? ? ? }
? ? ? }
? ? ? ?System.out.println("最大的数是:"+temp);
? }
}
/* 输出结果为
? ?无数字
? ?最大的数是:131.0
? ?最大的数是:32.0
*/
十七. 递归
能不用就不用
-
递归就是: A方法调用A方法,就是自己调用自己 -
利用递归可以用简单的程序来解决些复杂的问题。
-
递归结构包括两个部分:
案例:
public class Recursion {
? ?// 求一个数的阶层
? ?public static void main(String[] args) {
? ? ? ?System.out.println(f(5));
? }
? ?public static int f(int n){
? ? ? ?if (n==1){
? ? ? ? ? ?return 1;// 递归头
? ? ? }else {
? ? ? ? ? ?return n*f(n-1);// 递归体
? ? ? }
? }
}
// 输出结果为 120
十八. 数组
18.1. 数组的定义
18.2. 数组声明创建
案例:
public class Array {
? ?public static void main(String[] args) {
? ? ? ?int[] num = new int[5];
? ? ? ?num[0]=10;
? ? ? ?num[1]=20;
? ? ? ?num[2]=30;
? ? ? ?num[3]=40;
? ? ? ?num[4]=50;
? ? ? ?System.out.println(num[3]);
? }
}
// 输出结果为 40
18.3. 数组的初始化
-
静态初始化
-
动态初始化
-
int[] array = new int[2];
array[0]=1;
array[1]=2;
-
数组的默认初始化
18.4. 数组的四个基本特点
18.5. 多维数组
18.6. Arrays类
此类包含各种操作数组的方法(如:排序和搜索)
import java.util.Arrays;
?
public class Array {
? ?public static void main(String[] args) {
? ? ? ?int[] arrays01 = {11,22,380,4,50};
? ? ? ?int[] arrays02 = new int[5];
?
? ? ? ?// 打印数组元素
? ? ? ?System.out.println(Arrays.toString(arrays01)); ? // 输出结果为[11, 22, 380, 4, 50]
?
? ? ? ?// 数组升序(从小到大)
? ? ? ?Arrays.sort(arrays01); // 该方法无返回值,变化为永久的
? ? ? ?System.out.println(Arrays.toString(arrays01)); ? // 输出结果为[4, 11, 22, 50, 380]
?
? ? ? ?// 填充赋值
? ? ? ?Arrays.fill(arrays02,10);
? ? ? ?System.out.println(Arrays.toString(arrays02)); ? // 输出结果为[10, 10, 10, 10, 10]
? ? ? ?Arrays.fill(arrays02,1,3,20);
? ? ? ?System.out.println(Arrays.toString(arrays02)); ? // 输出结果为[10, 20, 20, 10, 10]
?
? ? ? ?// 比较数组元素值是否相等
? ? ? ?System.out.println(Arrays.equals(arrays01,arrays02)); // 输出结果为false
?
? ? ? ?// 查找数组元素(二分法)
? ? ? ?System.out.println(Arrays.binarySearch(arrays01,3)); ? ?// -1(无该元素,返回-1)
? ? ? ?System.out.println(Arrays.binarySearch(arrays01,4)); ? ?// 0(有该元素,返回下标)
? }
}
18.7. 冒泡排序
import java.util.Arrays;
?
//冒泡排序(升序、从小到大)
public class BubbleSort {
? ?public static void main(String[] args) {
? ? ? ?int[] array={23,12,545,88,1,8};
? ? ? ?System.out.println(Arrays.toString(bubbleSort(array)));// 输出结果为[1, 8, 12, 23, 88, 545]
? }
?
? ?public static int[] bubbleSort(int[] array){
? ? ? ?int temp=0;
? ? ? ?// 外层循环代表循环次数
? ? ? ?for (int i = 0; i < array.length; i++) {
? ? ? ? ? ?// 内层循环代表依次比较
? ? ? ? ? ?for (int j = 0; j < array.length-i-1; j++) {
? ? ? ? ? ? ? ?if (array[j]>array[j+1]){
? ? ? ? ? ? ? ? ? ?temp=array[j];
? ? ? ? ? ? ? ? ? ?array[j]=array[j+1];
? ? ? ? ? ? ? ? ? ?array[j+1]=temp;
? ? ? ? ? ? ? }
? ? ? ? ? }
? ? ? }
? ? ? ?return array;
? }
? ?
}
18.8. 稀疏数组
?以上图为例:
public class Array {
? ?// 1.创建一个二维数组,0:没有棋子,1:黑棋,2:白棋
? ?public static void main(String[] args) {
? ? ? ?// 展示原始数组
? ? ? ?int[][] arrays01 = new int[11][11];
? ? ? ?arrays01[1][2] = 1;
? ? ? ?arrays01[2][3] = 2;
? ? ? ?System.out.println("原始数组为:");
? ? ? ?arrayInfo(arrays01);
?
? ? ? ?// 转换为稀疏数组
? ? ? ?System.out.println("稀疏数组为:");
? ? ? ?int[][] arrays02 = sparseArray(arrays01);
? ? ? ?arrayInfo(arrays02);
?
? ? ? ?// 稀疏数组还原
? ? ? ?System.out.println("还原稀疏数组:");
? ? ? ?int[][] arrays03 = restoreSparseArray(arrays02);
? ? ? ?arrayInfo(arrays03);
? }
?
? ?// 遍历二维数组
? ?public static void arrayInfo(int[][] arrays){
? ? ? ?for (int[] ints : arrays) {
? ? ? ? ? ?for (int anInt : ints) {
? ? ? ? ? ? ? ?System.out.print(anInt+"\t");
? ? ? ? ? }
? ? ? ? ? ?System.out.println();
? ? ? }
? }
?
? ?// 转换为稀疏数组
? ?public static int[][] sparseArray(int[][] array){
? ? ? ?int count=0;// 获取有效值个数
? ? ? ?for (int i = 0; i < array.length; i++) {
? ? ? ? ? ?for (int j = 0; j < array[i].length; j++) {
? ? ? ? ? ? ? ?if(array[i][j]!=0){
? ? ? ? ? ? ? ? ? ?count++;
? ? ? ? ? ? ? }
? ? ? ? ? }
? ? ? }
? ? ? ?// 创建稀疏数组
? ? ? ?int[][] arrays00 = new int[count+1][3];
? ? ? ?arrays00[0][0] = array.length;// 原数组的行数
? ? ? ?arrays00[0][1] = array[0].length;// 原数组的列数
? ? ? ?arrays00[0][2] = count;// 原数组不为0的个数
?
? ? ? ?// 判断是否在外循环接受前,已经获取到了所有的非0值,提前退出循环
? ? ? ?int temp=1;
? ? ? ?// 获取非0的值行数、列数和值
? ? ? ?for (int i = 0; i < array.length; i++) {
? ? ? ? ? ?for (int j = 0; j < array[i].length; j++) {
? ? ? ? ? ? ? ?if(array[i][j]!=0){
? ? ? ? ? ? ? ? ? ?arrays00[temp][0]=i;
? ? ? ? ? ? ? ? ? ?arrays00[temp][1]=j;
? ? ? ? ? ? ? ? ? ?arrays00[temp][2]=array[i][j];
? ? ? ? ? ? ? ? ? ?temp++;
? ? ? ? ? ? ? }
? ? ? ? ? }
? ? ? ? ? ?if(temp==arrays00[0].length){
? ? ? ? ? ? ? ?break;
? ? ? ? ? }
? ? ? }
? ? ? ?return arrays00;
? }
?
? ?// 稀疏数组还原
? ?public static int[][] restoreSparseArray(int[][] array){
? ? ? ?//读取稀疏数组
? ? ? ?int[][] arrays00 = new int[array[0][0]][array[0][1]];
? ? ? ?// 还原值
? ? ? ?for (int i = 1; i <= array[0][2]; i++) {
? ? ? ? ? ?arrays00[array[i][0]][array[i][1]] = array[i][2];
? ? ? }
? ? ? ?return arrays00;
? }
}
/*输出结果为:
? ?原始数组为:
? ?0 0 0 0 0 0 0 0 0 0 0
? ?0 0 1 0 0 0 0 0 0 0 0
? ?0 0 0 2 0 0 0 0 0 0 0
? ?0 0 0 0 0 0 0 0 0 0 0
? ?0 0 0 0 0 0 0 0 0 0 0
? ?0 0 0 0 0 0 0 0 0 0 0
? ?0 0 0 0 0 0 0 0 0 0 0
? ?0 0 0 0 0 0 0 0 0 0 0
? ?0 0 0 0 0 0 0 0 0 0 0
? ?0 0 0 0 0 0 0 0 0 0 0
? ?0 0 0 0 0 0 0 0 0 0 0
? ?稀疏数组为:
? ?11 11 2
? ?1 2 1
? ?2 3 2
? ?还原稀疏数组:
? ?0 0 0 0 0 0 0 0 0 0 0
? ?0 0 1 0 0 0 0 0 0 0 0
? ?0 0 0 2 0 0 0 0 0 0 0
? ?0 0 0 0 0 0 0 0 0 0 0
? ?0 0 0 0 0 0 0 0 0 0 0
? ?0 0 0 0 0 0 0 0 0 0 0
? ?0 0 0 0 0 0 0 0 0 0 0
? ?0 0 0 0 0 0 0 0 0 0 0
? ?0 0 0 0 0 0 0 0 0 0 0
? ?0 0 0 0 0 0 0 0 0 0 0
? ?0 0 0 0 0 0 0 0 0 0 0
*/
十九. 三种初始化和内存分析
?
二十. 面向对象编程
20.1. 面向对象简介
20.1.1 面向过程与面向对象
20.1.2. 什么是面向对象
-
面向对象编程(Object-Oriented Programming, 00P) -
面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据 -
抽象 -
三大特性:
-
从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象 -
从代码运行角度考虑是先有类后有对象。类是对象的模板。
二十一. 类与对象
21.1. 类与对象
案例:
package com.oop;
?
public class Application {
? ?public static void main(String[] args) {
? ? ? ?Student xiaoming = new Student();
? ? ? ?xiaoming.name = "小明";
? ? ? ?xiaoming.age=20;
? ? ? ?System.out.println(xiaoming.name); // 小明
? ? ? ?System.out.println(xiaoming.age); // 20
?
? ? ? ?Student xiaohong = new Student();
? ? ? ?xiaohong.name = "小红";
? ? ? ?xiaohong.age=18;
? ? ? ?System.out.println(xiaohong.name); // 小红
? ? ? ?System.out.println(xiaohong.age); // 18
? }
}
?
-------------------------------------------------------------
?
package com.oop;
?
public class Student {
? ?String name=null;
? ?int age=0;
? ?public void study(){
? ? ? ?System.out.println("在学习");
? }
}
21.2. 构造器
-
构造方法名必须与类名相同 -
没有返回值 -
作用
-
使用new关键字,本质是在调用构造器 -
用来初始化值的 -
定义有参构造器后,若需要无参构造器,必须显示定义
package com.oop;
?
public class Application {
? ?public static void main(String[] args) {
? ? ? ?Person person01 = new Person();
? ? ? ?Person person02 = new Person("小明");
? ? ? ?Person person03 = new Person("小红",12);
? ? ? ?System.out.println(person01.name+" "+person01.age); // null 0
? ? ? ?System.out.println(person02.name+" "+person02.age); // 小明 0
? ? ? ?System.out.println(person03.name+" "+person03.age); // 小红 12
? }
}
?
-------------------------------------------------------------
? ?
package com.oop;
?
public class Person {
? ?String name;
? ?int age;
?
? ?public Person() { ? //无参构造器
? }
?
? ?public Person(String name) { // 有参构造器
? ? ? ?this.name = name;
? }
?
? ?public Person(String name, int age) {
? ? ? ?this.name = name;
? ? ? ?this.age = age;
? }
}
21.3. 封装
案例:
package com.oop.Demo01;
?
public class Application {
? ?public static void main(String[] args) {
? ? ? ?Student student = new Student();
? ? ? ?student.setName("小明");
? ? ? ?student.setAge(1000);
? ? ? ?System.out.println(student.getName());// 小明
? ? ? ?System.out.println(student.getAge());// 18
? }
}
?
-------------------------------------------------------------
? ?
package com.oop.Demo01;
?
public class Student {
? ?private String name;
? ?private int age;
?
? ?public Student() { }
?
? ?public Student(String name, int age) {
? ? ? ?this.name = name;
? ? ? ?this.age = age;
? }
?
? ?public void setName(String name) {
? ? ? ?this.name = name;
? }
? ?
? ?public void setAge(int age) {
? ? ? ?if (age>120 || age<0){
? ? ? ? ? ?this.age=18;
? ? ? }else{
? ? ? ? ? ?this.age = age;
? ? ? }
? }
? ?
? ?public String getName() {
? ? ? ?return name;
? }
? ?
? ?public int getAge() {
? ? ? ?return age;
? }
}
总结:
-
提高程序的安全性,保护数据 -
隐藏代码的实现细节 -
统一接口 -
系统可维护增加了
21.4. 继承
21.4.1. Object类
-
在java中所有的类都直接或者间接继承Object类(超类) -
继承的本质是对某一批类的抽象,以此实现对实现世界更好的建模 -
extends的意思是”扩展“,子类是父类的扩展 -
Java类只有单继承,没有多继承 -
继承是类和类之间的一种关系(除此之外,还有依赖、组合和聚合等...) -
继承关系的两个类,一个是子类,一个是父类,子类继承父类,使用关键字extends来表示 -
子类和父类之间,从意义上将应该具有”is a“关系
21.4.2. super 与 this
super注意点:
super与this的不同:
-
两者代表的对象不同
-
this:本身调用者的这个对象 -
super:代表父类对应的引用
-
两者前提不同
-
this:没有继承也能使用 -
super:只能在继承条件下使用
-
两者构造方法不同
-
this:本类的构造方法 -
super:父类的构造方法
package com.oop.Demo02;
?
public class Application {
? ?public static void main(String[] args) {
? ? ? ?Student student = new Student();
? ? ? ?student.info("小红");
? }
}
/* 输出结果为:
? ?小红
? ?小明
? ?小明爸爸
*/
?
?
-------------------------------------------------------------
? ?
package com.oop.Demo02;
?
public class Person {
? ?protected String name="小明爸爸";
}
?
-------------------------------------------------------------
? ?
package com.oop.Demo02;
?
public class Student extends Person{
? ?private String name="小明";
?
? ?public void info(String name){
? ? ? ?System.out.println(name);
? ? ? ?System.out.println(this.name);
? ? ? ?System.out.println(super.name);
? }
}
package com.oop.Demo02;
?
public class Application {
? ?public static void main(String[] args) {
? ? ? ?Student student = new Student();
? ? ? ?student.info();
? }
}
/*输出结果为:
? ?小明在学习
? ?小明在学习
? ?爸爸在工作
*/
-------------------------------------------------------------
? ?
package com.oop.Demo02;
?
public class Person {
? ?protected String name="小明爸爸";
?
? ?public void print(){
? ? ? ?System.out.println("爸爸在工作");
? }
}
?
-------------------------------------------------------------
? ?
package com.oop.Demo02;
?
public class Student extends Person{
? ?private String name;
?
? ?@Override
? ?public void print() {
? ? ? ?System.out.println("小明在学习");
? }
?
? ?public void info(){
? ? ? ?print();
? ? ? ?this.print();
? ? ? ?super.print();
? }
?
}
package com.oop.Demo02;
?
public class Application {
? ?public static void main(String[] args) {
? ? ? ?Student student = new Student("man","小明");
? ? ? ?student.info();//
?
? }
}
/*输出结果为:
? ?man
? ?小明
*/
-------------------------------------------------------------
? ?
package com.oop.Demo02;
?
public class Person {
? ?protected String sex;
?
? ?public Person() { }
?
? ?public Person(String sex) {
? ? ? ?this.sex = sex;
? }
?
? ?public void info(){
? ? ? ?System.out.println(this.sex);
? }
}
?
-------------------------------------------------------------
? ?
package com.oop.Demo02;
?
public class Student extends Person{
? ?private String name;
?
? ?public Student() { }
?
? ?public Student(String sex, String name) {
? ? ? ?super(sex);
? ? ? ?this.name = name;
? }
?
? ?@Override
? ?public void info(){
? ? ? ?super.info();
? ? ? ?System.out.println(this.name);
? }
}
21.4.3. 方法重写
-
注意:
-
重写的方法可以使用 @Override 注解来标识 -
声明为 final 的方法不能被重写 -
声明为 static 的方法不能被重写,但是能够再次声明 -
声明为 private 的方法不能被重写 -
构造方法不能被重写 -
子类和父类在同一个包中时,子类可以重写父类的所有方法,除了声明为 private 和 final 的方法 -
子类和父类不在同一个包中时,子类只能重写父类的声明为 public 和 protected 的非 final 方法 -
如果不能继承一个方法,则不能重写这个方法 -
重写的是方法,与属性无关
案例:
package com.oop.Demo03;
?
public class Application {
? ?public static void main(String[] args) {
? ? ? ?Student student01 = new Student();
? ? ? ?student01.info();
?
? ? ? ?Person student02 = new Person();
? ? ? ?student02.info();
?
? ? ? ?Person student03 = new Student();
? ? ? ?student03.info();
? }
}
/*输出结果为:
? ?Student.info
? ?Person.info
? ?Student.info
*/
-------------------------------------------------------------
? ?
package com.oop.Demo03;
?
public class Person {
? ?public void info(){
? ? ? ?System.out.println("Person.info");
? }
}
?
-------------------------------------------------------------
? ?
package com.oop.Demo03;
?
public class Student extends Person{
? ?@Override
? ?public void info() {
? ? ? ?System.out.println("Student.info");
? }
}
21.5. 多态
案例:
package com.oop.Demo04;
?
public class Application {
? ?public static void main(String[] args) {
? ? ? ?// 一个对象的实际类型是确定的
? ? ? ?//new Student();
? ? ? ?//new Person();
? ? ? ?
? ? ? ?// 可以指向的引用类型就不确定:父类的引用指向子类
? ? ? ?
? ? ? ?// Student 能调用的方法都是自己的成就的或者继承父类
? ? ? ?Student student1=new Student();
? ? ? ?// Person 父类,可以指向子类; 使用方法:成员变量,静态方法看左边;非静态方法:编译看左边,运行看右边
? ? ? ?// 可以简单理解为:编译时,对象能使用的方法都是父类决定的,而运行时,若被调用的方法已在子类的重写,则执行子类的方法;反之,则执行父类方法;而成员变量都是来自父类的
? ? ? ?Person student2=new Student();
? ? ? ?Object student3=new Student();
? ? ? ?
? ? ? ?student1.p();
? ? ? ?student2.p();
? ? ? ((Student) student3).p();
? }
}
/*输出结果为:
? ?s
? ?s
? ?s
*/
-------------------------------------------------------------
? ?
package com.oop.Demo04;
?
public class Person {
? ?public void p(){
? ? ? ?System.out.println("p");
? }
}
?
-------------------------------------------------------------
? ?
package com.oop.Demo04;
?
public class Student extends Person{
? ?@Override
? ?public void p() {
? ? ? ?System.out.println("s");
? }
}
21.6. instanceof
package com.oop.Demo05;
?
public class Application {
? ?public static void main(String[] args) {
? ? ? ?Object stu1 = new Student();
?
? ? ? ?System.out.println(stu1 instanceof Student);//true
? ? ? ?System.out.println(stu1 instanceof Person);//true
? ? ? ?System.out.println(stu1 instanceof Object);//true
? ? ? ?System.out.println(stu1 instanceof Animal);//true
?
? ? ? ?System.out.println(stu1 instanceof Teacher);//false
? ? ? ?System.out.println(stu1 instanceof String);//false
? ? ? ?
? ? ? ?System.out.println("=================================================");
?
? ? ? ?Object stu2 = new Person();
?
? ? ? ?System.out.println(stu2 instanceof Student);//false
? ? ? ?System.out.println(stu2 instanceof Person);//true
? ? ? ?System.out.println(stu2 instanceof Object);//true
? ? ? ?System.out.println(stu1 instanceof Animal);//true
?
? ? ? ?System.out.println(stu2 instanceof Teacher);//false
? ? ? ?System.out.println(stu2 instanceof String);//false
? ? ? ? ? ? ? ?
? ? ? ?System.out.println("=================================================");
?
? ? ? ?Student stu3 = new Student();
?
? ? ? ?System.out.println(stu3 instanceof Student);//true
? ? ? ?System.out.println(stu3 instanceof Person);//true
? ? ? ?System.out.println(stu3 instanceof Object);//true
? ? ? ?System.out.println(stu1 instanceof Animal);//true
?
? ? ? ?System.out.println(stu3 instanceof Teacher);//编译时报错
? ? ? ?System.out.println(stu3 instanceof String);//编译时报错
? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ?System.out.println("=================================================");
?
? ? ? ?Person stu4 = new Student();
?
? ? ? ?System.out.println(stu4 instanceof Student);//true
? ? ? ?System.out.println(stu4 instanceof Person);//true
? ? ? ?System.out.println(stu4 instanceof Object);//true
? ? ? ?System.out.println(stu4 instanceof Animal);//true
?
? ? ? ?System.out.println(stu4 instanceof Teacher);//false
? ? ? ?System.out.println(stu4 instanceof String);//编译时报错
? }
}
?
-------------------------------------------------------------
? ?
package com.oop.Demo05;
?
public class Animal{}
?
-------------------------------------------------------------
? ?
package com.oop.Demo05;
?
public class Person extends Animal{}
?
-------------------------------------------------------------
? ?
package com.oop.Demo05;
?
public class Teacher extends Person{}
?
-------------------------------------------------------------
? ?
package com.oop.Demo05;
?
public class Student extends Person{}
21.7. 类型转换
案例:
package com.oop.Demo06;
?
public class Application {
? ?public static void main(String[] args) {
? ? ? ?Person teacher = new Teacher();
? ? ? ?teacher.p(); //Person
? ? ? ((Teacher)teacher).t(); //Teacher
? }
}
-------------------------------------------------------------
?
package com.oop.Demo06;
?
public class Person{
? ?public void p(){
? ? ? ?System.out.println("Person");
? }
}
?
-------------------------------------------------------------
?
package com.oop.Demo06;
?
public class Teacher extends Person{
? ?public void t(){
? ? ? ?System.out.println("Teacher");
? }
}
二十二. static关键字详解
22.1. 静态变量和静态方法
package com.oop.Demo07;
?
public class Application {
? ?public static void main(String[] args) {
? ? ? ?Student s = new Student();
? ? ? ?System.out.println(s.age); ? ? ? ? ?//10
? ? ? ?s.studentName(); ? ? ? ? ? ? ? ? ? ?//小红
? ? ? ?System.out.println(Student.name); ? //小明
? ? ? ?Student.studentAge(); ? ? ? ? ? ? ? //18
? }
}
?
-------------------------------------------------------------
?
package com.oop.Demo06;
?
public class Student {
? ?int age=10; //非静态变量
? ?static String name="小明"; ? //静态变量
?
? ?public void studentName(){ //非静态方法
? ? ? ?System.out.println("小红");
? ? ? ?//studentName(); //非静态方法可以调用静态方法,静态不能调用非静态方法
? }
?
? ?public static void studentAge(){ //静态方法
? ? ? ?System.out.println(18);
? }
}
22.2. 静态代码块
package com.oop.Demo07;
?
public class Application {
? ?
? ?// 匿名代码块:类一加载就执行,可用于赋初始值
? {
? ? ? ?System.out.println("匿名代码块");
? }
?
? ?// 静态代码块:类一加载就执行,顺序比匿名代码块早,但永久只执行一次
? ?static {
? ? ? ?System.out.println("静态代码块");
? }
?
? ?// 当代码块都执行完后,再执行构造方法
? ?public Application(){
? ? ? ?System.out.println("构造方法");
? }
? ?public static void main(String[] args) {
? ? ? ?Application application = new Application();
? ? ? ?System.out.println("===============================");
? ? ? ?Application application1 = new Application();
? }
}
/* 输出结果为:
? ?静态代码块
? ?匿名代码块
? ?构造方法
? ?===============================
? ?匿名代码块
? ?构造方法
*/
22.3. 静态导入包
package com.oop.Demo07;
?
// 静态导入包
import static java.lang.Math.random;
?
public class Application {
? ?public static void main(String[] args) {
? ? ? ?System.out.println(random());
? }
}
二十三. 抽象类
package com.oop.Demo08;
?
public abstract class Person { // 抽象类
? ?public abstract void a(); // 抽象方法
? ?
? ?public Application() { // 构造方法
? }
? ?
? ?public void b() { // 非抽象方法
? ? ? ?System.out.println("hello");
? }
}
?
-------------------------------------------------------------
?
package com.oop.Demo08;
?
public class Student extends Person{
? ?@Override
? ?public void a() {
? ? ? ?System.out.println("world");
? }
}
二十四. 接口
package com.oop.Demo09;
?
public class UserServiceImpl ?implements UserNameService,UserAgeService{
? ?@Override
? ?public void addUserName(String name) {
?
? }
?
?
? ?@Override
? ?public void addUserAge(String name) {
?
? }
}
?
-------------------------------------------------------------
?
package com.oop.Demo09;
?
// 定义接口关键字是interface,
public interface UserNameService {
? ?// 接口中所有定义都是抽象的,public abstract
? ?void addUserName(String name);
}
?
-------------------------------------------------------------
?
package com.oop.Demo09;
?
public interface UserAgeService {
? ?void addUserAge(String name);
}
二十五. 内部类
package com.oop.Demo10;
?
public class Application {
? ?public static void main(String[] args) {
? ? ? ?// 外部类
? ? ? ?Outer outer = new Outer();
? ? ? ?outer.out();
? ? ? ?// 成员内部类
? ? ? ?Outer.Inner01 inner1 = outer.new Inner01(); ? ? ?// 通过外部类来实例化内部类
? ? ? ?inner1.in();
? ? ? ?inner1.getOutInfo();
? ? ? ?// 静态内部类
? ? ? ?Outer.Inner02 inner2 = new Outer.Inner02();
? ? ? ?inner2.in();
? ? ? ?inner2.getOuterInfo();
? ? ? ?// 局部内部类
? ? ? ?outer.outMethod();
? ? ? ?// 匿名内部类
? ? ? ?// 如果一个内部类在整个操作中只使用一次的话,就可以定义为匿名内部类。匿名内部类也就是没有名字的内部类,这是java为了方便我们编写程序而设计的一个机制,因为有时候有的内部类只需要创建一个它的对象就可以了,以后再不会用到这个类,这时候使用匿名内部类就比较合适。
? ? ? ?new ATest().info();
? }
}
?
class ATest{
? ?public void info(){
? ? ? ?System.out.println("匿名内部类");
? }
}
?
-------------------------------------------------------------
?
package com.oop.Demo09;
?
public class Outer {
?
? ?private int id=10;
? ?private static String name="小明";
?
? ?public void out(){
? ? ? ?System.out.println("这是外部类的方法");
? }
?
? ?// 成员内部类
? ?public class Inner01{
? ? ? ?public void in(){
? ? ? ? ? ?System.out.println("这是成员内部类的方法");
? ? ? }
?
? ? ? ?public void getOutInfo(){
? ? ? ? ? ?System.out.println(name); ? ? ? ? ? ? ? // 可以获取外部类的私有属性
? ? ? ? ? ?System.out.println(id);
? ? ? }
? }
?
? ?// 静态内部类
? ?public static class Inner02{
? ? ? ?public void in(){
? ? ? ? ? ?System.out.println("这是静态内部类的方法");
? ? ? }
?
? ? ? ?public void getOuterInfo(){
? ? ? ? ? ?System.out.println(name); ? ? ? ? ? ? ?// 静态类获取的外部类的私有属性必须是静态的
? ? ? }
? }
?
? ?// 局部内部类
? ?public void outMethod(){
? ? ? ?class Inner03{
? ? ? ? ? ?public void in(){
? ? ? ? ? ? ? ?System.out.println("这是局部内部类的方法");
? ? ? ? ? }
?
? ? ? ? ? ?public void getOuterInfo(){
? ? ? ? ? ? ? ?System.out.println(name); ? ? ? ? ? ? ? // 可以获取外部类的私有属性
? ? ? ? ? ? ? ?System.out.println(id);
? ? ? ? ? }
? ? ? }
?
? ? ? ?// 局部内部类需要在该方法的最后实例化
? ? ? ?Inner03 inner3 = new Inner03();
? ? ? ?inner3.in();
? ? ? ?inner3.getOuterInfo();
? }
}
?
二十六. 异常
26.1. 异常的种类
26.2. 异常的体系
26.2.1 Error
-
Error类对象由Java虚拟机生成并抛出的,大多数的错误与代码编写者所执行的操作无关。 -
Java虚拟机运行错误(Virtual MachineError),当JVM不再有继续执行操作所需的内存资源时,将出现OutOfMemoryError。当这些异常发生时,Java虚拟机(JVM) 一般会选择线程终止; -
还有发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError) 、链接错误(LinkageError) 。这些错误是不可查的,因为它们在应用程序的控制和处理能力外,而且绝大多数是程序运行时不允许出现的状况。
26.2.2. Exception
-
在Exception分支中有一个重要的子类RuntimeException (运行时异常) ,而它其中的重要子类有
-
ArraylndexOutOfBoundsException (数组下标越界) -
NullPointerException (空指针异常) -
ArithmeticException (算术异常) -
MissingResourceException (舌失资源) -
ClassNotFoundException (找不到类)等异常,这些异常是不检查异常,程序可以选择捕获处理,也可以不处理
-
这些异常一般是由程序逻辑错误引起的,程序员应该从逻辑角度尽可能避免这类异常的发生 -
Error和Exception的区别: Error通常是灾难性的致命的错误,是程序无法控制和处理的,当出现这些异常时, Java虚拟机(JVM)一般会选择终止线程; Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常。
26.3. 异常处理机制
-
抛出异常 -
捕获异常 -
异常处理五个关键字:try, catch, finally, throw, throws -
如果要不获取多个异常,要从小到大捕获
案例1----捕获异常:
package com.exception.Demo01;
?
public class Application {
? ?public static void main(String[] args) {
? ? ? ?try{
? ? ? ? ? ?System.out.println(20/0);
? ? ? }catch (ArithmeticException e1){ ? ? ? ? ? ? ? ? ? ? // 捕获异常
? ? ? ? ? ?System.out.println("ArithmeticException");
? ? ? }catch (Exception e2){
? ? ? ? ? ?System.out.println("Exception");
? ? ? }finally { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// finally可以不用写,用于善后工作,如在IO中在finally代码块内写关闭资源的代码
? ? ? ? ? ?System.out.println("finally用于善后工作");
? ? ? }
?
? ? ? ?System.out.println();
? }
}
?
/*输出结果为:
? ?ArithmeticException
? ?finally用于善后工作
*/
案例2----自动抛出异常:
package com.exception.Demo02;
?
public class Application {
? ?public static void main(String[] args) {
? ? ? ?int num=10;
? ? ? ?if (num==10) {
? ? ? ? ? ?throw new NumberFormatException(); // 自动抛出异常 throw 异常对象;
? ? ? } else {
? ? ? ? ? ?System.out.println(num);
? ? ? }
? }
}
26.4. 自定义异常
-
使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常 -
用户自定义异常类,只需继承Exception类即可 -
在程序中使用自定义异常类,大体可分为以下几个步骤:
-
-
创建自定义异常类,并继承Exception类 -
在方法中通过throw关键字抛出异常对象 -
如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作 -
在出现异常方法的调用者中捕获并处理异常
案例:
package com.exception.Demo03;
?
public class Application {
?
? ?static void test(int num) throws MyException{
? ? ? ?if (num<10){
? ? ? ? ? ?throw new MyException(num);
? ? ? }else {
? ? ? ? ? ?System.out.println("num="+num);
? ? ? }
? }
?
? ?public static void main(String[] args) throws MyException{
? ? ? ?try{
? ? ? ? ? ?test(8);
? ? ? }catch (MyException e){
? ? ? ? ? ?System.out.println("捕获异常为:"+e);
? ? ? }
? }
}
?
-------------------------------------------------------------
?
package com.exception.Demo03;
// 自定义异常
public class MyException extends Exception{
? ?private int num;
?
? ?// 传递大于10的数字
? ?public MyException(int num) {
? ? ? ?this.num = num;
? }
?
? ?// toString 打印异常信息
? ?@Override
? ?public String toString() {
? ? ? ?return "MyException{" + "num=" + num + '}';
? }
}
?
/*输出结果为:
捕获异常为:MyException{num=8}
*/
总结:
-
处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理 -
在多重catch块后面,可以加一个catch (Exception)来处理可能会被遗漏的异常 -
对于不确定的代码,也可以加上try-catch,处理潜在的异常 -
尽量去处理异常,切忌只是简单地调用printStackTrace()去打印输出 -
具体如何处理异常,要根据不同的业务需求和异常类型去决定 -
尽量添加finally语句块去释放占用的资源
|