JavaSE自学笔记

本文最后更新于:1 年前

JavaSE自学笔记(本人所看b站视频狂神说Java

初识Java

博客

自建博客

[Hexo博客的搭建与部署](Hexo博客的搭建部署 - Linsip)

MarkDown语法

[MarkDown语法笔记](Markdown语法 - Linsip)

常用Dos命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//退回上级目录
cd ..

//退回到根目录
cd\

//进入某文件夹
cd 文件夹路径

//新建文件夹
md 文件夹名

//删除文件夹
rd 文件夹名

//拷贝文件
copy 文件路径 目标路径 文件

//删除文件
del 文件路径 文件

//查看目录下所有文件
dir 路径

//格式化硬盘(别乱用!!!!)
format 盘符

//清理屏幕(clean screen)
cls

//退出
exit

计算机语言发展史(简史)

计算机语言可以分为机器语言、汇编语言、高级语言三类,其对应的计算机语言发展历史的三个阶段

第一阶段

1946年2月14日,世界上第一台计算机ENAC诞生,使用的是最原始的穿孔卡片。这种卡片上使用的语言是只有专家才能理解的语言,与人类语言差别极大,这种语言就称为机器语言。机器语言是第一代计算机语言。这种语言本质上是计算机能识别的唯一语言,人类很难理解。以后的语言就是在这个的基础上简化而来。虽然后来发展的语言能让人类直接理解但最终送入计算机的还是这种机器语言。

第二阶段

计算机语言发展到第二代,出现了汇编语言。汇编语言用助记符代替了操作码,用地址符号或标号代替地址码。这样就用符号代替了机器语言的二进制码。汇编语言也称为符号语言。比起机器语言,汇编大大进步了。尽管还是复杂,用起来容易出错,但在计算机语言发展史上是机器语言向更高级的语言进化的桥梁

第三阶段

当计算机语言发展到第三代时,就进入了“面向人类”的高级语言。高级语言是一种接近于人们使用习惯的程序设计语言。它允许用英文写计算程序,程序中的符号和算式也与日常用的数学式子差不多。高级语言发展于20世纪50年代中叶到70年代,流行的高级语言已经开始固化在计算机内存里了,比如 basic语言。现在,计算机语言仍然在不断的发展,种类也相当多,比如 FORTRAN语言, COBOL语言,C语言,C++,C#, PASCAO,JAVA等等。

原文请看:计算机语言的发展简史-马海祥博客 (mahaixiang.cn)

Java的历史(简史)

1991年4月,James Gosling领导的Green Project计划,致力于开发一种适用于各种电子性消费产品的程序架构,诞生了Java的前身–Oak

1995年5月23日,Oak被更名为Java,由Sun公司在Sun World上正式发布。第一次提出了“Write once,Run anywhere”的口号

···

JDK

JDK(Java Development Kit)称为Java开发包或Java开发工具,是一个编写Java的Applet小程序和应用程序的程序开发环境。JDK是整个Java的核心,包括了Java运行环境(Java Runtime Environment),一些Java工具和Java的核心类库(Java API)

来源:百度百科

安装JDK:JDK官网

推荐下载Java SE 8或者Java SE 11

JRE

Java运行环境(Java Runtime Environment,简称JRE)是一个软件,由太阳微系统所研发,JRE可以让计算机系统运行Java应用程序(Java Application)。

JRE的内部有一个Java虚拟机(Java Virtual Machine,JVM)以及一些标准的类别函数库(Class Library)。

来源:百度百科

HelloWorld

第一行代码

尝试用记事本写下下面这几行代码或者推荐使用Notepad++

并且在命令提示符上编译运行出来

1
2
3
4
5
6
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}

编译型与解释型

编译型:简单来说就像是一个翻译,对我们写的的源代码进行翻译,生成计算机能看得懂的可执行代码

解释型:一边翻译,一边执行

Java(解释型+编译型):java是通过javac.exe编译成.class文件 然后通过jvm加载.class文件,然后调用java.exe执行文件。在此之前你要下载安装JDK并配置环境变量。

IDEA

先了解什么是IDE

集成开发环境(IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面等工具。集成了代码编写功能、分析功能、编译功能、调试功能等一体化的开发软件服务套。所有具备这一特性的软件或者软件套(组)都可以叫集成开发环境。如微软的Visual Studio系列,Borland的C++ Builder、Delphi系列等。该程序可以独立运行,也可以和其它程序并用。IDE多被用于开发HTML应用软件。例如,许多人在设计网站时使用IDE(如HomeSite、DreamWeaver等),因为很多项任务会自动生成。

来源:百度百科

IDEA业界公认最好的Java开发工具

下载:IDEA官网

安装:按自己需求安装,或者默认安装

配置环境变量

  1. 我的电脑–>属性–>高级系统设置–>高级–>环境变量
  2. 在打开的系统变量中新建变量,变量名:JAVA_HOME,变量值:JDK安装目录
  3. 系统变量中Path下添加如下内容%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
  4. 测试是否配置成功cmd
1
java -version

基础语法

注释

单行注释 Line comment

1
2
3
4
5
6
7
8
9
10
//注释 这就是注释的基本格式,到本行结束所有的字符被编译器忽略
//public class Demo01 表示定义了一个类 名称为Demo01 修饰符为public,其中类名称必须与文件名称相同
public class Demo01 {
//main方法,代表一个程序的起点
public static void main(String[] args) {
//打印输出语句(屏幕显示)
System.out.println("Hello World!");
}
}

多行注释 block comment

1
2
3
4
5
6
7
8
9
10
11
/*
多行注释
多行注释
多行注释
*/
public class Demo02 {
public static void main(String[] args) {
System.out.println("China NO.1!");
}
}

文档注释JavaDoc

1
2
3
4
5
/**
*@author
*@version
*@since
*/

参数

参数信息
@author 作者
@version 版本号
@since 指明最早使用jdk版本
@param 参数名
@return 返回值
@throws 抛出异常情况

拓展:如何用IDEA生成自己的api文档?

Tools——Generate JavaDoc

标识符

定义

Java的所有组成部分都需要名字。类名、变量名、方法名都被称为标识符

命名规则

类名:首字母大写的驼峰命名,例如

1
public class Demo {}

变量名:首字母小写的驼峰命名规则

1
2
int num = 10;
int getNum = 100;

方法名:首字母小写的驼峰命名规则

1
void getMax() {}

注意事项

  • 所有的标识符都应该以字母A-Z,a-z美元$或者下划线**_**开始

  • 标识符大小写敏感

  • 标识符可以用中文但是不建议

  • 不得使用Java中的关键字作为标识符

关键字

什么是关键字?

有特殊含义的,被保留的,不能随意使用的字符

java中一共有53个关键字(不用记忆)

Java常用关键字

abstract default if private this
boolean do implements protected throw
break double import public throws
byte else instanceof return transient
case extends int short try
catch final interface static volatile
char finally long strictfp while
class float native super
const for new switch
continue goto package synchronized

注意事项

  • 关键字都是是完全小写的字母

  • Java中的true和false不是关键字

  • Java中有两个特殊关键字(Java保留字,Java不用,你也不能用)goto,const。

数据类型

java是一种强类型语言,即java的变量的使用要严格符合规定,先定义再使用

强类型语言:所有变量的定义必须严格符合规定,必须先定义后使用。安全性高,速度慢

弱类型语言

JS VB

Java的数据类型分为基本数据类型引用类型

基本数据类型

8种基本数据类型primitive type

整数类型

类型 占位 最值
byte 8bit 0x7f~0x80 (127)
short 16bit 0x7fff~0x8000 (32767)
int 32bit 0x7fffffff~0x80000000 (21亿)
long 64bit 字面量需要使用L后缀

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Demo01{
public static void main(String[] args){
//八大基本数据类型

//整数类型
int num1 = 10;//最常用
byte num2 = 20;
short num3 = 30;
long num4 = 40L;//long类型要在数字后加一个L

//浮点数
float num5 = 10.1F;//float类型要在数字后面加F
double num6 = 3.14;

//字符
char name = 'a';

//字符串,String不是关键字,是一个类
//String name = "马林";

//布尔值
boolean flag = true;
}
}

浮点类型

float(浮点型):32bit

double(双精度):64bit

类型 占位 最值
float 32 (-2^31)~(2^31-1) float类型精度过低,很少使用(一般都用double),字面量后缀F
double 64 浮点数的字面量默认为double,字面量后缀D

字符类型

char(字节型):16bit

类型 占位 取值
char 16 0~2^16-1 char是一个2进制数(16位无符号整数),这个数值是一个unicode编码

编码拓展

某个数除了表示一个数之外,还可以表示为一个字符

Unicode编码是全球范围内的编码方法

1
2
3
4
5
6
7
8
9
10
11
12
13
package datatype;
/*
编码拓展
Unicode编码
65--A
97--a
*/
public class Demo02 {
public static void main(String[] args) {
char c = 65;
System.out.println(c);//A
}
}

特殊字符用转义字符表示

转义字符 代表的意思
\n 回车
\t 制表
···

布尔类型

boolean类型:用于表达真假。常用于判断语句。

类型 占位 取值
boolean 1 false true 默认值为false

引用类型reference type

类:

接口:

数组:

类型转换

Java是强类型语言,进行有些运算的时候需要用到类型转换。

不同类型的数据先转换为同一类型的数据,然后进行计算

1
2
3
char c = 'a';
int i = 1;
System.out.println((int)c+i);//98

基本数据类型转换

基本数据类型转换分为强制类型转换自动类型转换(隐式类型转换)

自动类型转换方向

char–>int–>long–>float–>double

byte–>short–>int–>long–>float–>double

强制类型转换方向

char<–int<–long<–float<–double

byte<–short<–int<–long<–float<–double

强制类型转换会出现内存溢出的情况

1
2
3
int i = 128;
byte b = (int)i;//内存溢出
System.out.println(b);//-128

也可能有精度问题

1
2
3
double d1 = 20.7;
int i = (int)d1;
System.out.println(i);//20

操作比较大的数的时候注意溢出问题

1
2
3
4
5
6
7
8
9
10
11
public class Demo
public static void main(String[] args){
int money = 10_0000_0000;//JDK7的新特性,数字之间加_用于区分数字,计算不受影响
int year = 20;
int total = money*year;//计算的时候溢出了
long total2 = money*year;//默认类型int,右边在计算之前就出现问题
System.out.println(total);//-1474836480
System.out.println(total2);//-1474836480
//解决方法:在计算之前先转换数据类型
long total3 = money*(long)year;
}

自动类型转换 低–高,不会存在内存溢出的问题。

注意点

  • 不能对布尔类型进行转换
  • 不能将变量类型转换为不相干的类型
  • 把高容量数据转换为低容量数据 ,须强制转换
  • 转换的时候会有内存溢出或者精度问题的情况

引用类型转换

向下转型:小类型转大类型

向上转型:大类型转小类型

instanceof:检查引用对象的类型

变量与常量

变量

变量就是可以变化的量

Java变量是程序的最基本的存储单元,其要素包括变量名变量类型作用域

1
2
数据类型 变量名 = 值;可以用逗号隔开用于声明多个同类型变量。
type varName [=value] [{,varName[=value]}];

注意事项

  • 每个变量都有其类型,可以是基本类型,也可以是引用类型。
  • 变量名必须为合法的标识符。
  • 变量的声明是一条完整的语句,因此每个声明都必须以分号结束。

变量的作用域

  • 类变量
  • 实例变量
  • 局部变量
1
2
3
4
5
6
7
public class Variable{
static int allClicks = 0;//类变量 加了static的变量 从属于类,随着类出现和消失
String str = "hello world!";//实例变量:从属于对象,在类的里面,方法的外面,如果不进行初始化,则会变为该数据类型的默认值 0 0.0 u0000 false null(除了基本类型其他的都是null)
public void method(){
int i = 0;//局部变量
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Demo {
//类变量 static
static int salary = 2500;
//属性:变量,类里面除了方法还可以定义一些属性
//实例变量,从属于对象
String name;
int age;
//main方法
public static void main[String[] args]{

//局部变量;必须声明和初始化值
int i = 10;
System.out.println(i);

//变量类型 变量名 = new Demo();
Demo demo = new Demo();
System.out.println(demo.name);
System.out.println(demo.age);
}

public void add(){
System.out.println(i);
}
}

变量的命名规范

所有的变量、方法、类名:见名知意

类成员变量:首字母小写和驼峰原则:monthSalary

常量:大写字母和下划线 MAX_VALUE

类名:首字母大写和驼峰原则 Demo

方法名:首字母小写和驼峰原则 run() getMax()

常量:初始化后不能改变的值

常量

可以理解为一种特殊的变量,他的值被设定后,在程序运行期间不会改变

常量名一般用大写字母表示

1
2
final 常量名 = 常量值;
final PI = 3.14;
1
2
3
4
5
6
7
8
9
public class Demo{

static final double PI = 3.14;//修饰符不分前后

public static void main [String[] args]{
System.out.println(PI);
}
}


运算符

算数运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Demo01{
//算数运算符
public static void main[String[] args]{
int a = 10;
int b = 20;
int c = 30;
int d = 40;
int e = 21;
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(e%a);//%取余 也叫模运算 即21/10=2...1 21%10=1
}
}

注意事项

  • 整数除法运算,会出现下溢出现象
1
2
3
4
5
6
7
public class Demo02 {
public static void main(String[] args) {
int a = 4;
int b = 3;
System.out.println(a/b);//1 下溢出,余数1被舍弃
}
}
  • 低于int类型(short)(byte)的运算都按int类型运算
1
2
3
4
5
6
7
8
9
10
11
12
13
public class Demo {
public static void main[String[] args]{
long a = 111222333222111L;
int b = 123;
short c = 10;
byte d = 8;
//
System.out.println(a+b+c+d);//Long
System.out.println(b+c+d);//Int
System.out.println(C+D);//Int

}
}

模运算

(%)表示计算除法的余数

​ 0对其他数的余数为0

​ 负数的余数是负数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package datatype;

public class Demo {
public static void main(String[] args) {
int i1 = 11;
int i2 = 2;
int i3 = 0;
int i4 = -11;
System.out.println(i1 % i2);//1
System.out.println(i3 % i2);//0
System.out.println(i4 % i2);//-1
}
}

自增自减

1
2
3
4
5
6
7
8
9
10
11
12
public class Demo{
public static void main(String[] args){
//++ -- 自增 自减
int a = 3;
int b = a++;//表示a先赋值给b,然后再自增1
System.out.println(a);//4
int c = ++a;//表示a先自增1,然后赋值给c
System.out.println(a);//5
System.out.println(b);//3
System.out.println(c);//5
}
}

赋值运算符

=赋值运算符表示把等号右边的赋值给左边

==才是现实意义上的等于,属于关系运算符

关系运算符

1
2
3
4
5
6
7
8
9
10
public class Demo{
public static void main (String[] args){
//关系运算符,返回的是布尔值 false true
int a = 10;
int b = 20;
System.out.println(a>b);
System.out.println(a<b);
System.out.println(a==b);
}
}

逻辑运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//逻辑运算符
public class Demo{
pubic static void main(String[] args){
//&&与 ||或 !非
boolean a = true;
boolean b = false;

System.out.println("a&&b:"+(a&&b));
System.out.println("a||b"+(a||b));
System.out.println("!(a&&b)"+!(a&&b));

//短路运算,进行逻辑与运算时会发生短路运算
int c = 5;
boolean d = (c<4)&&(c++<4);//这里发生了短路运算,与运算下,c<4为false,计算机就不会计算&&后面的c++<4,所以c还是5,不会自增
System.out.println(c);//5
System.out.println(d);//false
}
}

位运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//位运算
public class Demo{
/*
A = 0011 1100
B = 0000 1101

A&B = 0000 1100 如果A与B两个二进制数对应位上都为1,结果才为1,否则就是0
A|B = 0011 1101 如果A与B两个二进制数对应位上都为0,结果才为0,否则就是1
A^B = 0011 0001 如果A与B两个二进制数相对应位上相同就为0,不同就为1
~B = 1111 0010 取反

2*8怎么运算最快?2*2*2*2
0000 0000 0
0000 0001 1
0000 0010 2
0000 0011 3
0000 0100 4
...
0001 0000 16

<< *2
>> /2
*/
public static void main(String[] args){
//2*8怎么运算最快?2*2*2*2
System.out.println(2<<3);
}
}

拓展

如何进行幂运算

1
2
3
4
5
6
7
public class Demo{
public static void main(String[] args){
//幂运算 很多运算需要用到一些工具类
double pow = Math.pow(2,3);//2^3 Math工具类位于Java.lang包下,其方法都是静态方法,直接类名.方法名就可以使用
System.out.println(pow);
}
}

条件运算符

1
2
3
4
5
6
7
8
9
10
11
//三元运算符
public class Demo {
public static void main{
//x?y:z
//如果x为true,结果就为y,否则就为z

int score = 80;
String type = score<60?"不及格":"及格";
System.out.println(type);//及格
}
}

拓展赋值运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//拓展运算符
public class Demo{
public static void main(String[] args){
int a = 10;
int b = 20;

a+=b;
a-=b;
a*=b;
a/=b;

//字符串连接符+ +遇到String类型的会变为字符串连接符
System.out.println(""+a+b);//1020
System.out.println(a+b+"");//30
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Demo {
public static void main[String[] args]{
long a = 111222333222111L;
int b = 123;
short c = 10;
byte d = 8;
//
System.out.println(a+b+c+d);//Long
System.out.println(b+c+d);//Int
System.out.println(C+D);//Int

}
}

包机制

为了更好的组织类,java提供了包机制,用于区别类名的命名空间

包语句的语法格式

1
package pkg1[.pkg2[.pkg3...]];

一般利用公司域名的倒置作为包名比如www.baidu.com>com.baidu.www

为了使用某一个包的成员,我们需要在java程序中导入该包。

1
import package1[.package2...].(classname|*);

JavaDoc

用idea生成api帮助文档

Tools–>Generate JavaDoc

generateJavaDoc

流程控制

Scanner类

Scanner类的hasNext()与hasNextLine()判断是否还有输入的数据

通过Scanner类的next()与nextLine()方法获取输入的字符串

示例一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.util.Scanner;//导包语句,Idea自动生成
public class ScannerDemo {
public static void main(String[] args){
//创建一个Scanner对象
Scanner scanner = new Scanner(System.in);
//判断用户有没有输入字符串
if (scanner.hasNext()){
//
String str = scanner.next();
System.out.println("输入的内容为:"+str);
}
//关闭scanner,凡是属于IO流的类不关闭就会一直占用资源
scanner.close();
}
}

示例二:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.util.Scanner;
public class ScannerDemo02 {
public static void main(String[] args) {
//创建一个Scanner对象
Scanner scanner = new Scanner(System.in);
//提示用户输入
System.out.println("输入名字");
//判断用户是否输入
if (scanner.hasNextLine()) {
//String类用于接收
String name = scanner.nextLine();
//打印出名字
System.out.println(name);
}
//关闭scanner,减少资源占用
scanner.close();

}
}

next():

  • 一定读取到有效字符后才结束输入
  • 有效字符前的空格,会被方法忽略
  • 有效字符后面的空格,会被方法当为结束符

next()方法不能得到带有空格的字符串

nextLine():

  • 以回车作为结束符
  • 可以获得空格

练习题1:输入多个数字,并求出总和与平均数,通过非数字的输入来结束输出并输出执行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Scanner;

public class ScannerDemo03 {
public static void main(String[] args) {
//定义两个变量用于后面的求和与计算平均数
double sum = 0;
int num = 0;
//new一个Scannner类的对象
Scanner scanner = new Scanner(System.in);
//用循环来判断是否输入的是数字,以及求和,累计数字个数
while (scanner.hasNextDouble()) {
sum += scanner.nextDouble();
num++;
}
//输出结果
System.out.println("输入数字的个数为" + num);
System.out.println("输入数字的和为:" + sum);
System.out.println("输入数字的平均数为" + (sum / num));
//关闭scanner
scanner.close();
}
}

顺序结构

顺序结构是Java的基本结构,除非特别指明,否则就按从上到下,从左到右,一句一句的执行。

顺序结构是最基本的算法结构,是任何算法都离不开的一种基本算法结构。

选择结构

if - else语句

基本语法:

if单选择结构语法

1
2
3
if (布尔表达式) {
语句
}

if双选择结构语法

1
2
3
4
5
if(布尔表达式){
语句1
}else {
语句2
}

if多选择结构语法

1
2
3
4
5
6
7
8
9
if(布尔表达式1){
语句1
}else if(布尔表达式2){
语句2
}else if(布尔表达式3){
语句3
}else{
语句4
}

示例

1
2
3
4
5
6
7
8
9
10
public class IfDemo {
public static void main (String[] args){
int i = 1;
if(i==1){
System.out.println("Hello World!");
}else{
System.out.println("你好,世界!")
}
}
}

练习1:输入成绩,判断成绩,60以上成绩合格,60以下成绩不合格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class IfDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入成绩:");
if (scanner.hasNextInt()) {
int i = scanner.nextInt();
if (i >= 60 && i <= 100) {
System.out.println("成绩合格");
} else if (i >= 0 && i < 60) {
System.out.println("成绩不合格");
} else {
System.out.println("非法成绩!!!");
}
}else{
System.out.println("请输入整数!!!");
}
}
}

switch - case语句

基本语法

1
2
3
4
5
6
7
switch () {
case 字面量:
代码;
break;
default 字面量:
代码;
}

注意点

  • switch不能处理long类型,Java se7开始 switch支持String类型
  • case后面必须为数字或者字面量,不能写语句
  • default表示没有满足case条件的其他一切情况
  • 不要忘记写break,不写会出现”case穿透“,后面的case、default都会执行

循环结构

while循环

基本语法

1
2
3
while (布尔表达式) {
循环体
}

示例

1
2
3
4
5
6
7
8
9
10
public class WhileDemo {
public static void main(String[] args) {
//输出1~100
int i = 0;
while (i<100){
i++;
System.out.println(i);
}
}
}

注意点

  • 循环体内一定要有能让布尔表达式为false的情况,否则就是死循环,会一直执行循环体

死循环

当我们有特殊需求需要使用死循环的时候

例如:输出0~无限大

1
2
3
4
5
6
7
8
9
public class WhileDemo01 {
public static void main(String[] args) {
int i = 0;
while (true) {
i++;
System.out.println(i);
}
}
}

尽量不要这么写,cpu会卡死!!!

do - while循环

基本语法

1
2
3
do {
//循环体语句
} while (布尔表达式);

相对于while循环,do-while循环会至少执行一次循环体

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class DoWhileDemo {
public static void main(String[] args) {
int a = 0;

while (a < 0) {
a++;
System.out.println(a);
}
do {
a++;
System.out.println(a);//这里会输出1
} while (a < 0);
}
}

for循环

基本语法

1
2
3
for (初始化语句;布尔表达式;更新) {
//循环体语句
}

注意点:

  • 先执行初始化语句,初始化语句可以初始化一个或多个循环控制变量,也可以为空
  • 然后执行布尔表达式,布尔表达式为true则执行一次循环体语句,之后是更新语句,布尔表达式,循环体语句……直到布尔表达式为false就执行终止循环

练习题1:计算0~100之间奇数与偶数的和

1
2
3
4
5
6
7
```



练习题2:用for循环输出1~1000之间能被5整除的数,每行三个

```java

练习题3:打印九九乘法表

1
2
3
4
5
6
7
8
9
10
11
12
```

**增强for循环**

Java5引入了一种主要用于数组或者集合的增强型for循环

语法格式

```java
for (声明语句:表达式) {
//代码
}

注意点

  • 声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环体语句块,其值与此时数组元素的值相等。
  • 表达式:表达式是要访问的数组名或者是返回值为数组的方法。

break & continue

break在任何循环体主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中的剩余语句。

continue语句实在循环体语句中,用于阻止某次循环,即跳过循环体中未执行的语句,接着进行下一次是否执行循环的判定。

拓展:

goto关键字很早就在程序设计语言中出现。尽管goto仍是Java的一个保留字,但并未在语言中得到正式的使用;Java没有goto。然而在break和continue这两个关键字上,可以看到goto的影子————带标签的break和continue

标签是指后面跟一个冒号的标识符例如:label

对于Java来说,唯一用到标签的地方是在循环语句之前。在循环语句之前设置标签的唯一理由是:我们希望在其中嵌套另一个循环,因为break和continue关键字只会终止当前循环,但是如果和标签一起使用,他们就会中断到存在标签的地方

方法

urn语句

局部变量

方法的参数的参数定义,是临时变量(空壳,相当于声明变量而没有赋值)

例如

1
2
3
4
5
6
7
8
9
10
11
12
public class MethodDemo{
public static void main (String[] args){
//这里的sum()方法中的1,2就是实参
int a = sum(1,2);
System.out.println(a);
}

public static int sum (int a,int b){//这里的int a,int b就是形参
return a+b;
}
}

方法调用

方法重载

重载就是在一个类中,有相同的函数名称,但是形参不同的函数。

方法的重载必须满足下列规则:

​ 方法名称必须相同

​ 参数列表必须不同

​ 返回值类型可以相同也可以不同,仅仅返回值类型的不同不足以构成方法的重载。

实现理论:

​ 方法名称相同时,编译器会根据调用方法的参数个数、参数类型去逐个匹配,以选择对应的方法,如果匹配失败则编译器报错。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class Demo {
public static void main(String[] args){
double max = max(10.1,10.0);
System.out.println(max);
}

//比大小
public static int max(int num1,int num2){
int result = 0;

if(num1==num2){
System.out.println("num1==num2");
return 0;//这里的return用于终止该方法。
}

if (num1>num2){
result = num1;
}else{
result = num2;
}
return result;
}

public static double max(double num1,double num2){
double result = 0;

if(num1==num2){
System.out.println("num1==num2");
return 0;//这里的return用于终止该方法。
}

if (num1>num2){
result = num1;
}else{
result = num2;
}
return result;
}
}

命令行传参

有时候你希望运行一个程序时再给它传递消息,这要靠传递命令行参数给main()函数实现。

1
2
3
4
5
6
7
public class CommandLine {
public static void main(String[] args){
for(int i =0;i<args.length;i++){
System.out.println("args["+i+"]"+args[i]);
}
}
}

可变长参数

JDK1.5开始,Java支持传递同类型的可变参数给一个方法。

在方法声明中,在指定的参数类型后加一个省略号(…)

一个方法只能指定一个可变参数,它必须是方法的最后一个参数。任何普通参数必须在它之前声明。

可变参数的本质是一个数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void printMax(double...numbers){
if(numbers.length == 0){
System.out.println("No argument passed!");
return;
}

double result = numbers[0];

//
for (int i =1; i<numbers.length;i++){
if (numbers[i]>result){
result =numbers[i];
}
}
System.out.println("The max value is "+result);
}

递归

A方法调用B方法

递归就是:A方法调用A方法

利用递归可以用简单的程序来解决一些复杂的问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需要少量的程序就可描述出解题过程中所需要的多次重复计算,大大减小了程序的代码量。递归的功能在于利用有限的语句来定义对象的无限集合。

递归结构包括两个部分:

​ 递归头:什么时候不调用自身方法。如果没有头将陷入死循环。

​ 递归体:什么时候需要调用自身方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Demo{
//递归
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);
}
}
}

数组

数组的定义

数组是拥有相同数据类型数据的有序集合

其中,每个数据都称为数组的元素,每一个数组元素可以通过下表访问他们。(下标从0开始)

声明数组

1
2
arrayType[] arrayRefVar;//首选写法
arrayType arrayRefVar[];//也是数组的声明,但是不建议这样写(c和c++的数组是这样写的)

分配空间

1
arrayRefVar = new arrayType[arraySize];

声明数组和分配空间可以合并一句来写

1
arrayType[] arrayRefVar = new arrayType[arraySize]; 

赋值

数组是通过索引访问的,索引从0开始;

1
2
3
arrayRefVar[0] = 1;
arrayRefVar[1] = 2;
...

没有赋值的数据元素有默认值,默认值和数组类型有关

处理数据

获取数组长度arrays.length

1
arrayRefVar.length

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ArrayDemo01{
public static viod main (String[] args){
//数组的声明
int[] array;
//分配数组空间
array = new int[5];
//分配数值,数组下标从0开始
array[0] = 1;
array[1] = 2;
array[2] = 3;
array[3] = 4;
array[4] = 5;
//遍历数组
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}

数组的三种初始化

静态初始化:创建+赋值

1
2
int[] array = {1,2,3};//基本类型
Man[] mans = {new Man(),new Man()};//引用类型

动态初始化

1
2
3
4
int[] array = new int[3];
array[0] = 1;
array[1] = 2;
array[2] = 3;

默认初始化

数组相当于引用类型,它的元素相当于类的实例变量,一旦数组被分配空间,其元素也就和类中的实例变量一样,被隐式初始化。

注意点

  • 数组数据类型确定,不存在混合类型的数组
  • 数组长度确定,数组一旦被创建,其长度就确定,而且不可改变
  • 数组可以为任何数据类型,包括基本类型和引用类型
  • 数组变量属于引用类型,也可以看为对象,每个数组元素可以看为该数组对象的成员变量,数组的本身就是对象,无论数组元素保存的是基本类型数据还是引用类型数据,数组都是保存在堆中的。

总结

数组是相同类型数据的有序集合

数组属于引用类型,数组也是对象,数组元素相当于成员变量

数组长度不可变 0~array.length-1,越界则会报错:ArrayIndexOutOfBoundsException即数组下标越界异常

最早遇到的错误

ArrayIndexOutOfBoundsException:数组下标越界异常

数组的使用

for each循环

数组作为方法入参

数组作为返回值

二维数组

二维数组:数组中嵌套数组,可以看为2行3列的数组

1
int[][] arrays = new int[2][3];

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package array;
/*
多维数组
二维数组

*/
public class ArrayDemo02 {
public static void main(String[] args) {
/*
1,2
2,3
3,4
4,5
*/
int[][] arrays ={{1,2},{2,3},{3,4},{4,5}};
System.out.println(arrays[0]);
printArray(arrays[0]);
System.out.println();
System.out.println(arrays[0][0]);
System.out.println(arrays[0][1]);
//遍历二维数组
for (int i = 0; i <arrays.length;i++) {
for (int j = 0; j <arrays[i].length; j++) {
System.out.println(arrays[i][j]);
}
}

}
//打印数组元素
public static void printArray(int[] arrays){
for (int i = 0; i <arrays.length; i++) {
System.out.print(arrays[i]+" ");
}
}

}

Arrays工具类

数组的工具类 java.util.Arrays

数组对象本身并没有什么方法供我们使用,但是我们可以借助API提供的Arrays工具类来帮我们对数组对象进行一些基本的操作

JDK帮助文档

Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名调用

Arrays类常用功能

  • 给数组赋值:fill
  • 对数组排序:sort
  • 比较数组:equals
  • 查找数组元素:binarySearch

排序算法

冒泡排序

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package array;

import java.util.Arrays;

/*
冒泡排序
比较相邻的两个数组元素,如果第一个数组元素比第二个数组元素大,那么便交换他们的位置
每一次循环,都会产生一个最大,一个最小的
下轮排序可以少一次排序
一次循环直到结束
*/
public class ArrayDemo07 {
public static void main(String[] args) {

int[] arrays = {12, 3, 4, 5, 76, 8, 89};
int[] result = bubbleSort(arrays);
System.out.println(Arrays.toString(result));


}

//冒泡排序
public static int[] bubbleSort(int[] a) {
//定义一个临时变量,用于内层循环交换数组元素
int temp = 0;
//外层循环,判断循环多少次
for (int i = 0; i < a.length - 1; i++) {
//内层循环,判断相邻两个数组元素的大小,并交换位置
for (int j = 0; j < a.length - 1 - i; j++) {
if (a[j + 1] < a[j]) {
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
//返回数组a
return a;
}
}

面向对象

面向对象与面向过程

  • 面向过程
    • 第一步…第二步…
    • 面向对象适合处理一些较为简单的问题
  • 面向对象
    • 分类的思维,思考问题首先需要解决问题有那些分类,然后对于这些分类进行单独思考,最后对于分类下的细节进行面向过程的探索
    • 面向对象适合处理复杂的问题,适合处理需要多人协作的问题
  • 对于复杂的事物,需要先从宏观上把握、从整体上分析,我们需要使用面向对象的思路来分析整个系统。然后在具体到微观细节,需要用面向过程的思路去解决。

属性+方法就是一个类

什么是面向对象

  • 面向对象的本质就是:以类的方式组织代码,以对象的形式组织(封装)数据
  • 抽象
  • 面向对象的三大特性
    • 封装:把数据封装
    • 继承:子类继承父类
    • 多态:
  • 如何理解类与对象
    • 从认识论的角度:现有对象后有类。对象是具体的事物。类是抽象的,是对对象的抽象。
    • 从代码角度考虑先有类后有对象,类是对象的模板

回顾方法

- 方法的定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package oop.review;

import java.io.IOException;

public class MethodRev {
//这是一个main方法
public static void main(String[] args) {

MethodRev methodRev = new MethodRev();

System.out.println(methodRev.sayHello());
}

//我们可以自定义一个方法来使用
public String sayHello() {
return "Hello";
}

//抛出异常,后面学
public String readFile(String file) throws IOException {
return null;
}
}

- 方法的调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package oop.review;

/*
静态方法:有static修饰的方法
带有static关键字的方法和类一起加载
非静态方法:没有static修饰的方法
对象创建之后才存在
*/
public class Demo01 {

public static void main(String[] args) {
//静态方法的调用
Student.say();
//非静态方法的调用,先实例化这个类,然后在通过对象.方法名调用
Student student = new Student();
student.eat();
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package oop.review;
/*
静态方法可以直接调用静态方法
静态方法不能直接调用非静态方法(要实例化之后,通过对象名.方法名调用)
非静态方法可以直接调用静态方法
*/

public class Demo02 {
public static void a() {
b();
}

public static void b() {
a();
}

public void c() {
a();
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package oop.review;

public class Demo03 {
public static void main(String[] args) {
int sum = new Demo03().add(123, 123, 231);
System.out.println(sum);
}

public int add(int... a) {
int sum = 0;
for (int i = 0; i < a.length; i++) {
int num1 = a[i];
sum += num1;
}
return sum;
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
package oop.review;

public class Student {

public static void say() {
System.out.println("学生说话了");
}

public void eat() {
System.out.println("学生吃东西了");
}
}

类与对象

类是一种抽象的数据类型,它是对某一类整体事物的描述、定义,但是不能代表某一个具体的事物

比如说 Student类 Pet类等等都是用来描述、定义某一类事物该有的特点和行为

对象是抽象概念的具体实例

比如说张三家的小狗旺财就是Pet类的一个具体实例

简单小结类与对象

  1. 类与对象

    1. 类是一个抽象的
    2. 对象是具体的
  2. 方法

    1. 方法的定义、调用
  3. 对应的引用

    1. 引用类型:除了八大基本类型
    2. 对象通过引用来操作的:栈》》》堆
  4. 属性:字段 field 成员变量

    1. 默认初始化
      1. 数字:0
      2. char:u0000
      3. boolean:false
      4. 引用:null
    2. 修饰符 引用类型 属性名 = 属性值
  5. 对象的创建及使用

    1. 必须用new关键字创建对象 构造器 Person person = new Person()
    2. 对象的属性 person.name
    3. 对象的方法:person.sleep()
    1. 静态的属性 属性
    2. 动态的行为 方法

构造方法

new对象

创建与初始化对象

使用new关键字创建对象

1

使用new关键字创建对象的时候,除了分配内存空间外,还会给创建好的对象进行默认的初始化以及对类中的构造器的使用

封装

该露的露,该藏的藏

  • 我们设计程序追求高内聚,低耦合,高内聚是指类的内部数据的操作细节自己完成,不允许外部干涉;低耦合是指尽量暴露少的方法给外部使用

封装(数据的隐藏)

  • 通常,应该禁止直接访问一个对象中的数据的实际表示,而是应该通过操作接口来访问,这成为信息的隐藏

属性私有,get/set

提高程序安全性,保护数据

隐藏代码实现细节

统一接口

提升系统的可维护性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package oop.demo04;

/*
get用来获取private修饰的数据
set用来设置private修饰的数据
*/
public class Student {
private String name;
private int age;
private char sex;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public char getSex() {
return sex;
}

public void setSex(char sex) {
this.sex = sex;
}

//睡觉
public void sleep() {
System.out.println("正在睡觉");
}

//学习
public void study() {
System.out.println("正在学习");
}
}

继承

继承的本质是对一批类的抽象,从而实现对世界的更好的建模

extends:本意拓展,子类是父类的拓展

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package oop.demo04;

public class Person {

/*
修饰符
public 公共的,都可以访问
protected
default
private 私有的,属于本类的

子类继承父类,只能继承父类public修饰的属性、方法

*/


public int money = 10_0000_0000;
public void say(){
System.out.println("说了一句话");
}
}

1
2
3
4
5
6
package oop.demo04;
//学生is Person

public class Student extends Person{
}

1
2
3
4
5
6
package oop.demo04;
//学生is Person

public class Student extends Person{
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package oop;


import oop.demo04.Student;

/*
规范:一个项目应该只存在一个main方法

*/
public class Application {
public static void main(String[] args) {

Student s1 = new Student();
//Student类里面没有say()方法,Student类继承了Person类,可以执行Person类里面的Say()方法
s1.say();

}

}

java只有单继承没有多继承

继承是类与类之间的关系,类与类的关系还有依赖、组合、聚合等

具有继承关系的两个类,一个叫子类,一个叫父类,子类继承父类,用关键字extends表示

object类

  • java中所有的类默认继承Object类,Object类是所有类的超级父类
  • 快捷键ctrl+h:查看层级结构

image-20210425120953321

super

  • 调用父类的构造方法
  • 必须只能出现在子类的方法或者构造方法中
  • super和this不能同时出现在构造方法中

vs this

  • this:代表本身调用者这个对象,没有继承也可以用
  • super:代表父类对象的引用,只能在继承关系下使用

构造方法

  • this():调用本类的构造
  • super():调用父类的构造

方法的重写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package oop;

import oop.demo05.A;
import oop.demo05.B;


/*
规范:一个项目应该只存在一个main方法

*/
public class Application {
public static void main(String[] args) {
//方法的调用之和左边的类型有关
A a = new A();
a.test();

//父类的引用指向子类对象
B b = new A();
b.test();


}

}

1
2
3
4
5
6
7
8
package oop.demo05;

public class A extends B{
public static void test(){
System.out.println("A>test");
}
}

1
2
3
4
5
6
7
8
9
10
11
package oop.demo05;
/*
重写:重写是方法的重写,与属性无关

*/
public class B {
public static void test(){
System.out.println("B>test");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
package oop.demo05;

public class A extends B{
@Override//注解,有功能的注释
public void test() {
System.out.println("A>test");
}
}
/*
静态方法和非静态方法有很大的区别
静态方法不能被重写,静态方法的调用只和左边的类型有关
非静态方法可以被重写(只能是public的方法),他的调用只和new
*/
1
2
3
4
5
6
7
8
9
10
11
package oop.demo05;
/*
重写:重写是方法的重写,与属性无关

*/
public class B {
public void test(){
System.out.println("B>test");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package oop;



import oop.demo05.A;
import oop.demo05.B;


/*
规范:一个项目应该只存在一个main方法

*/
public class Application {
public static void main(String[] args) {
//方法的调用之和左边的类型有关
A a = new A();
a.test();

//父类的引用指向子类对象
B b = new A();
b.test();


}

}

重写是方法的重写,与属性无关

重写注意点

  1. 重写必须有继承关系
  2. 参数列表必须相同
  3. 修饰符:可以被扩大,不可以被缩小 private< default< protected< public
  4. 抛出的异常:可以被缩小,不能被扩大

为什么需要重写

  1. 父类的方法子类不一定需要或者满足alt insert>>>override

多态

同一方法可以根据发送方法的不同,采取多种不同的行为方式

一个对象的实际类型是确定的,但是可以指向对象的引用的类型有很多

多态的前提

  • 有继承关系
  • 子类重写父类方法
  • 父类引用指向子类对象

多态是方法的多态,属性没有多态性

intsanceof

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package oop;


import oop.demo06.Person;
import oop.demo06.Student;
import oop.demo06.Teacher;

public class Application {
public static void main(String[] args) {

Object o = new Student();

System.out.println(o instanceof Student);//ture
System.out.println(o instanceof Person);//ture
System.out.println(o instanceof Object);//ture
System.out.println(o instanceof Teacher);//false
System.out.println(o instanceof String);//false

/*
思考
Person
Student
Teacher
*/

}

}

1
2
3
4
5
package oop.demo06;

public class Teacher {
}

1
2
3
4
5
6
7
8
package oop.demo06;

public class Person {
public void run(){
System.out.println("run");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
package oop.demo06;

public class Student extends Person{
@Override
public void run() {
System.out.println("s run");
}

public void eat(){
System.out.println("s eat");
}
}

注意点

  1. 多态是方法的多态
  2. 子类父类,不是继承关系会有类型转换异常ClassCastException
  3. 多态的前提

static方法不能被重写

final方法不能被重写

private方法不能被重写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package oop;


import oop.demo06.Person;
import oop.demo06.Student;

public class Application {
public static void main(String[] args) {
/*
一个对象的类型是确定的
new Student();
new Person();
可以指向的引用可以不同
Person s1 = new Student();
Student s2 = new Student();
*/
Student s1 = new Student();
Person s2 = new Student();
Object s3 = new Student();

//Student能调用的方法都是自己的,或者继承父类的
s1.run();
//Person能调用的方法只能是
s2.run();

s1.eat();
((Student)s2).eat();




}

}

1
2
3
4
5
6
7
8
package oop.demo06;

public class Person {
public void run(){
System.out.println("run");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
package oop.demo06;

public class Student extends Person{
@Override
public void run() {
System.out.println("s run");
}

public void eat(){
System.out.println("s eat");
}
}

修饰符

抽象类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package oop.demo08;
/*
abstract抽象类
抽象类不能new出来,只能靠子类去实现他
抽象类里面可以写普通方法,但是抽象方法只能在抽象类中
抽象的抽象:约束

抽象类是否存在构造器
*/
public abstract class Action {
//约束,有人帮我们完成某些功能的具体实现
//抽象方法,abstract修饰的方法,只有方法的名字没有方法的实现
public abstract void doSomething();
}

1
2
3
4
5
6
7
8
9
10
11
12
package oop.demo08;
/*
抽象类的所有方法都必须由子类实现(重写),除非子类也是抽象的
*/
public class A extends Action{

@Override
public void doSomething() {

}
}

接口

普通类:只有具体实现

抽象类:具体实现和规范(抽象方法)都有

接口:只有规范

接口就是规范,定义的是一组规则,体现了现实世界中“如果你是…你必须能…”的思想

接口的本质就是契约,制定好后大家都要遵守

OO的精髓是对对象的抽象,最能体现这一点的就是接口,我们讨论设计模式都是针对具备抽象能力的语言(c,java,c#),设计模式研究的就是如何去抽象

interface声明接口

class声明类

作用:

  1. 约束
  2. 定义一些不同的方法,让不同的人去实现
  3. public abstract
  4. public static final
  5. 接口不能被实例化,接口没有构造方法
  6. implements可以实现多个接口
  7. 必须要重写接口中的方法

内部类

内部类就是在一个类的内部再定义一个类,比如,A类中定义一个B类,那么B类相对于A类来说就是一个内部类,或者说A类相对于B类是外部类

  1. 成员内部类

    1. ```java
      package oop.demo10;

      public class Outer {

      private int id = 100;
      public void out(){
          System.out.println("这是外部方法");
      }
      
      public class Inner{
          public void in(){
              System.out.println("这是内部方法");
          }
          public void getId(){
              System.out.println(id);
          }
      }
      

      }

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26

      2.

      2. 静态内部类

      1. static

      2. ```java
      package oop.demo10;

      public class Outer {
      private int id = 100;
      public void out(){
      System.out.println("这是外部方法");
      }

      public static class Inner{
      public void in(){
      System.out.println("这是内部方法");
      }
      public void getId(){
      System.out.println(id);
      }
      }
      }

  2. 局部内部类

    1. ```java
      package oop.demo10;public class Outer {
      //局部内部类
      public void out(){
      
          class Inner{
      
              public void in(){
      
              }
          }
      
      
      }
      
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23

      2.

      4. 匿名内部类

      ```java
      package oop.demo10;

      public class Test {
      public static void main(String[] args) {
      //有名字初始化类
      Apple apple = new Apple();
      apple.eat();
      //没有名字初始化类
      new Apple().eat();
      }
      }

      class Apple {
      public void eat() {
      System.out.println("1");
      }
      }

异常

概念

异常:在程序执行过程中,出现了非正常的情况,最终会导致JVM的非正常停止

在java等面向对象的编程语言中,异常本来就是一个类,产生异常就是创建一个异常对象并抛出了一个异常对象。java处理异常的方式是中断处理。

Throwable

throwable

五个关键字

自定义异常

使用java内置的异常类可以描述在编程时出现的大部分异常情况。除了这些异常,我们可以自定义异常

如何自定义异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package exception.demo02;
/*
自定义异常
1.创建自定义异常类
2.在方法中通过Throw关键字抛出异常对象
3.如果要在当前抛出异常的方法中处理异常,可以用try-catch语句捕获异常,并处理异常;否则就在方法的声明出通过throws关键字
指明要抛出给方法调用者的异常
4.在出现异常的方法的调用者中处理和捕获异常
*/


//1.创建自定义异常类,继承Exception类
public class MyException extends Exception {
//传递数字,>10就抛出异常
private int detail;

public MyException( int a) {
this.detail = a;
}

@Override
public String toString() {//异常的打印信息
return "MyException{" +
"detail=" + detail +
'}';
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package exception.demo02;

public class Test {
//可能会存在异常的方法
static void test (int a) throws MyException {
System.out.println("传递的参数为"+a);
if (a>10) {
throw new MyException(a);
}
System.out.println("OK");
}

public static void main(String[] args) {
try {
test(11);
} catch (MyException e) {
System.out.println("MyException"+e);
}
}
}

异常总结

处理运行时异常时,采用逻辑去合理规避同时辅助try-catch

在多重catch块后面,可以加一个catch(Excption)来处理可能被遗漏的异常

对于不确定的代码,也可以加try-catch,来处理潜在的异常

尽量去处理异常,切忌只简单地调用printStackTrace()去打印输出

具体如何处理异常要根据不同的业务需求和异常类型去决定

尽量添加finally语句去释放已经占用的资源


博主码字不易,本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!