半小时复习Java全内容


来都来了点个赞呗 o(*≧▽≦)ツ

这段时间要急着考试的同学,可以看我画的重点,目录上有标识,如果时间充裕也可以详细看下去,会很有帮助的。我会用视频加图画来解释。这篇文章中,包括对java的深度理解,以及内存数据的演变。对与理解计算机是有重要帮助。

(๑•̀ㅂ•́)و✧


Java语法全栈

  • 半小时复习Java全内容
  • 一级目录
    • 二级目录
      • 三级目录
  • 前言
  • 一、初识Java
    • 1.Java的安装
      • 1.1下载JDK
      • 1.2JDK安装与使用
        • 1.2.1安装
        • 1.2.2 IDEA(编译器)使用
    • 2.Java运行编程逻辑(重要后面要用)
    • 总结
  • 二、数据类型与变量(重要)
    • 2.数据类型
      • 2.1 基本数据类型
    • 1.变量与常量
      • 1.1常量(字面常量)
      • 1.2变量
      • 数据类型小总结
  • 三、运算符
    • 1.运算符号(重要)
      • 1.1计算运算符
      • 1.2增量运算符
      • 1.3 自增或自检运算符
      • 1.4关系运算符
  • 注意:
    • 2.逻辑符号(重要)
      • 2.1&&的语法结构:**表达式 1 && 表达式 2**
      • 2.2 || 的语法结构:**表达式 1 || 表达式 2**
      • 2.3 ! 的语法结构:** !表达式 **
  • 注意
    • 3.位运算符(重要但是看实际需要)
      • 3.1按位与 &
      • 3.2按位或 |
      • 3.3按位取反 ~
      • 3.4按位异或 ^
      • 4.移位运算符
  • 注意
    • 5.条件运算符(三目运算符)
    • 运算符小总结
  • 四、逻辑控制
    • 1.if...else(常用)
      • 1.1表达格式(三种)
    • 2.switch...case(用的少)
      • 2.1表达式
    • 3.while(常用)
      • 3.1语法格式
      • 3.2关键字beak:
      • 3.3关键字 continue:
    • 4.for.....(常用)
      • 4.1语法格式
    • 5.while...do(不常用)
      • 5.1基本语法
    • 逻辑控制小总结
  • 五、方法
    • 1.定义
    • 2.模块化
      • 1.实参和形参的关系
    • 3.重载(重要后边有大用)
    • 4.重写(重要后边有大用)
    • 5.递归(重要,一种思维方式)
    • 方法小总结
  • 六、数组(非常重要)
    • 1.定义
    • 2.遍历
      • 2.1遍历方法
      • 2.2Arrays方法
    • 3.二维数组
    • 数组小总结
  • 七、类和对象
    • 1. 定义(重要)
      • 1.1 类
      • 1.2 对象
    • 2. this关键字(重要)
      • 2.1 特点
    • 3. 构造方法(重要)
      • 3.1实现方式
      • 3.2作用
    • 4. 封装
      • 4.1包权限(重要)
      • 4.2静态成员static(重要)
    • 5.代码块
      • 5.1 静态代码块(重要)
      • 5.1同步代码块(多线程会出现)
    • 6.内部类(重要)
      • 6.1静态内部类
      • 6.2非静态/实例内部类
      • 6.3匿名内部类(不着急他的主要途径是在抽象类中)
    • 类和对象的小总结
  • 八、继承和多态(重要)
    • 1.继承
      • 1.1 定义
      • 1.2 关键字super
      • 1.3 关键字 final
    • 2.多态
      • 2.1定义
      • 2.2 重写
      • 2.3 向上/向下转型
    • 继承和多态的小总结
  • 九、抽象类与接口(重要)
    • 1.抽象类
    • 2.接口
      • 2.1定义
      • 2.2 实现
    • 抽象类与接口的小总结
  • 十、异常(重要)
    • 1.常见类型
    • 2.实现
    • 异常的小总结
  • 十一、其他文章接口
    • 1.String方法(重要,对于操作字符串有巨大的帮助)
    • 2.java常用的接口及其方法(包含拷贝,比较,排序,构造器)
    • 3.初阶数据结构
      • 3.1 顺序表:ArrayList
      • 3.2 链表:LinkedList
      • 3.3 栈:Stack
      • 3.4 队列:Queue
      • 3.5 二叉树:Tree
      • 3.6 优先级队列:PriorityQueue(堆排序)
      • 3.7 Map和Set
    • 4. 排序(7种方式)
      • 4.1 插入排序(两种)
      • 4.2 选择排序(两种)
      • 4.3 快速排序
      • 4.4 堆排序
      • 4.5 归并排序
    • 5.多线程
    • 6.网络编程
    • 7.HTML
    • 8.数据库Mysql
    • ...........
  • 总结

一级目录

二级目录

三级目录

前言

学习很重要,复习也很重要,对于编程语言的复习更为重要。语法是编程的基础。也是逻辑编程(计算机程序编程)诞生的最根本的语言体系。学会了语法了就等于学会了计算机编程的四分之一。剩下的就需要去学习,数据结构与算法,计算机组成原理,与计算机操作系统。这里没有将数据库列入,只要是数据库的语言语法可以是数据结构与算法和编程语言的结合。后面我会在出继续更新相关内容,当然也包括数据库。

编译语言:java

编译环境:Windows

编译器:IDEA


一、初识Java

java是一个面向对象的经典编程语言,Java语法是C++语法的一个“纯净版本”,相当于对C++做了一个减法。(对象的概念将会在下面类和对象中详细说明)

1.Java的安装

学习Java就得先学会在计算机系统上安装java,这里我们选择在Windows上安装,在Linux中安装这里不做解释,详情可以看目录十一。

1.1下载JDK

首先我们去官网下载JDK,现在jdk的版本用的最多的是1.8版本,因为它足够稳定。在实际运用中稳定和安全就是程序的一切。
链接:https://www.java.com/en/download/(官网一般不好进
链接:https://www.oracle.com/java/technologies/javase/javase8u211-later-archive-downloads.html(文件在最下方,看准参照物8u311

需要登录甲骨文才能下载(嫌麻烦可以直接去我网盘中下载:链接:https://pan.baidu.com/s/1fFAAHYpi7UwBzSuv3bZv3g
提取码:1111)没用可以私信我

在安装前一定要看自己的Windows 系统的类型,我的是64位,右击此电脑或者我的电脑,选择属性就可以看见。

1.2JDK安装与使用

一般而言,计算机软件我们都不推荐在C盘安装。在C盘安装会影响计算机的运行。但是JAVA特例,我们通常安在C盘,这样使得Java的优先级更高。无需去其他盘访问。(因为我已经安装过1.9了所以只做演示)

1.2.1安装

下一步就可

一定要记住自己安装位置,诺不知道安装路径可以在C盘右上角搜索Java关键字



在这里我们就安好了,但是想要进行使用,就必须配置Java相关的环境。我们先去安装的文件夹中找到java的jdk。

可以看见安装后就会出现一个jdk文件夹和jar文件夹

jre:

jre 是java runtime environment, 是java程序的运行环境。既然是运行,当然要包含jvm,也就是虚拟机,还有所有java类库的class文件,都在lib目录下打包成了jar。在windows上的虚拟机是jre/bin/client里面是一个jvm.dll。

jdk:

jdk 是java development kit,是java的开发工具包,主要是给ide 用的,里面包含了各种类库和工具。当然也包括了另外一个Jre.,而且jdk/jre/bin 里面也有一个server文件夹, server文件夹下面也有一个jvm.dll 虚拟机。(这个虚拟机是什么后,面会涉及)

环境配置

首先用鼠标右键点开我的电脑或者此电脑找到属性,然后在找到高级系统配置


系统变量和用户变量的区别

系统变量:是计算机唯一且永久的变量,诺是切换用户,并不会影响计算机关键软件的运行。

用户变量:它会随着你计算机用户的变更而变更,切换用户后诺此用户没有进行相关配置,将无法使用上个用户的软件

所以我们在这里选择计算机系统变量,配置环境。



环境一定不能出错不然无法运行java

变量名:JAVA_HOME(记住一定要大写

变量值:C:\Program Files\Java\jdk1.8.0_192
(记住这是我的路径,不是你的路径,要配置成功一定要换成自己的路径

变量名:classpath(这次要小写

变量值,;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
(你没有看错,最前面%前面有一个英文的逗号和分号

%JAVA_HOME%代表的是jdk的路径




到这里基本上配置完毕了,要验证是否配置成功按住Windows健+r弹出运行窗口,输入cmd,弹出DOS命令窗口


输入java -version

显露出这些信息我们就算是将Java安装完毕了,在这里你可以发现我的是1.9版本,这是因为我在配置时配置的是1.9版本,虽然下载的java版本很多但是在环境配置中我配置的是java1.9版本。所以可以看出java版本是互相不干扰的,只要想用哪个,就配置哪个就完事。

自检自己安装的版本就好

1.2.2 IDEA(编译器)使用

我这里用的2022版本,这里请自行下载,作为程序员谁也不希望自己成功被人免费盗用(其实作为学生的话,IDEA是可以免费使用的,前提需要认证,不知道怎么做可以去B站上找教程:链接:https://www.bilibili.com/video/BV19V411k7HD?t=12.2)

安装好后
我们先创建一个项目


到这里我们的java编程的基本准备就算完成了

2.Java运行编程逻辑(重要后面要用)

如何执行java文件?

可以看见在中间的方框中有我圈出了两个按钮。一个是Run(运行),一个是Debug(调试)

Run:再点击后会在你所创建的项目中生成一个class文件(一般这代表着你的代码没有任何问题,可以交付给用户)风险大

Debug:将代码在编译器中进行调试,可以将代码的错误风险在IDEA中调试中降到最低,也可以创建的项目中生成一个class。

他们两个都会生成一个out的IEDA所属的运行文件目录,class文件就会在里面生成,这个class文件叫字节码文件

这个是我没有进行任何操作的项目文件

我们先做用Debug来调试一下这个java文件。

这个就是我们的运行结果

我们去他相关的文件夹看一看,可以看见out的文件夹下的子目录下生成了一个class文件

我们在试试Run,看看是不是会生成一个class文件

可以看出Run和Debug的运行结果一样,但是在窗口出现的字符不同。

java文件不在ide中运行


JDK、JRE、JVM之间的关系

JDK:Java开发工具包,提供给Java程序员使用,包含了JRE,同时还包含了编译器javac与自带的调试工具Jconsole、jstack等。

JRE:Java运行时环境,包含了JVM,Java基础类库。是使用Java语言编写程序运行的所需环境。

JVM:Java虚拟机,运行Java代码

总结

  1. 源文件名后缀是.java
  2. 类名与文件名不一致(编译器会报错)
  3. main方法名字写错:mian(主方法就只有一个)
  4. 类没有使用public修饰(为什么后面会说)
  5. 方法中语句没有以分号结尾(重要,而且所有字符必须用英文输入法)
  6. 中文格式的分号
  7. JDK环境没有配置好,操作系统不能识别javac或者java命令

二、数据类型与变量(重要)

2.数据类型

在实际运用会有,不同的应用就诞生了不同的数据需求,从而衍生出了一些基本的数据类型。

2.1 基本数据类型

1byte=8bit(内存最小单位)(也叫二进制位)

通常计算机表示数据用二进制表

数据类型 关键字 内存占用 范围(可以用的范围)
字节型 byte 1 字节 -128 ~ 127
短整型 short 2 字节 -32768 ~ 32767
整型 int 4 字节 -2^31 ~ 2^31-1
长整型 long 8 字节 -2^63 ~ 2^63-1
单精度浮点数 float 4 字节 有范围,一般不关注
双精度浮点数 double 8 字节 有范围,一般不关注
字符型 char 2 字节 0 ~ 65535
布尔型 boolean 没有明确规定 true 和 false

可以看见数据类型共分有8种基本类型。而八种基本类型中又分4种大类型

四类整型、浮点型、字符型,布尔型

特点:注意

  1. 不论是在16位系统还是32位系统,int都占用4个字节,long都占8个字节
  2. 整形和浮点型都是带有符号的
  3. 整型默认为int型,浮点型默认为double

1.变量与常量

在实际应用中,有始终不变的常量,如太阳的升起的位置,而有些内容可能会经常改变,比如人的身高,它会随着人的生长而发生变化。

1.1常量(字面常量)

常量 例子
字符串常量 由 " " 括起来的,比如“12345”、“hello”、“你好”。
整形常量 程序中直接写的数字,比如:1235456,1000 (注意没有小数点)
浮点数常量 程序中直接写的小数,比如:3.14
字符常量 由 单引号 括起来的当个字符,比如:‘a、‘2’(ASCII码上都是)
布尔常量 只有两种true和false
空常量 null(简单而言没有任何数据的量,甚至连0都不是)

注意:字符串、整形、浮点型、字符型以及布尔型,在Java中都称为数据类型

1.2变量

故名思意,就是会变得量,如何定义一个变量?

数据类型 变量名 = 初始值;

一个变量在内存中如何存储?我们用int类型来举例:一个变量在内存中存储,会转换为二进制。

数据在内存上的存储

不同种类的数据类型进行交叉保存会怎么样?比如:int类型的变量去保存short类型,而short类型去保存int类型。

由上面视频和基本类型的存储空间大小就可以知道,int的存储大小为4个字节,short的存储大小为2个字节。所以可以得出结论,存储的数据一定不能超出类型的存储大小。

再看看这个例子。

我们打印一下看看

哎?数据变了,是不是很有意思。按道理来说,b的值是999999赋值给t了,t应该是999999才对啊。就算只有t只有两个字节,那么他的大小也该是32767,不应该是16959才对啊。

咱们再看一个视频

强制类型装换的危害

在括号里加上类型,叫做强制数据类型转换,而这种情况就有可能会向视屏中的样子一样丢失数据。从而使运算结果发生变化。

数据类型小总结

  1. 由基本类型存储空间就可以了解到,他们的存储大小不同。存储的数据量也有所不同
  2. 强制类型装换:小—>大(可以),大—>小(可能可以,危险度高)
  3. 引用数据类型(后面讲)可以提一下:String就是引用数据类型
  4. String(俗称字符串类型)不是基本数据类型

三、运算符

计算机诞生之初就是为了计算,复杂而庞大的数据。比如严格意义上第一个电子计算设备是图灵为了在二战中抵御德军侵略,创造出的计算德军情报密钥的机器。这台设备在二战中发挥了不可替代的作用。而如何计算,就要用到逻辑的运算符

1.运算符号(重要)

对操作数进行操作时的符号,不同运算符操作的含义不同

1.1计算运算符

我们先定义两个元素(我们这里先不考虑类型):a=5 ,b =2

计算机运算符 数学计算逻辑 机器计算逻辑 结论
+ a + b = 7 a+b=7 取整
- b - a = - 2 b - a = - 2 取整
* a * b =10 a * b =10 取整
/ a / b = 2.5 a / b = 2 取整
% 没有这个计算逻辑 a % b = 5 余数化整
演化一下% a % b = 2…1 a % b = 1 取余

特点:

  1. 除法在计算机中分为两种:
    一种叫做取整“ / ”,会将小数点前面的留下并丢弃小数点后面的。
    一种叫做取余(也有叫法一个数磨一个数)“ % ”,除去整数后,会保留余下来的数。
  2. 如果要保留小数,只需要在定义变量时加上浮点类型就行。
  3. 在计算时符合数学逻辑,所以被除数不能为0,
    10 % 0(x)
    10 / 0 (x)

1.2增量运算符

+= - = *= %= /=
 int a=1;a+=1; //相当于a=a+1;System.out.println(a);//结果等于2//*****************************a-=1;//相当于a=a-1;//*****************************a*=3;//a=a*3//*****************************a%=10;//a=a%10//*****************************a/=3;// a=a/3;

注意:

  1. ‘ = ’ :等号的意思是,将右边的值赋予左边
  2. 程序是由上倒下运行的,所以如果我这个代码在编译器执行,会直接扰乱我们想要的结果。这里只是方面你们观察。

1.3 自增或自检运算符

(++,–)

++ - -
        int b=0;//这个叫后置++,他会先使用原来的值,然后再进行+1b++;//此时值为:1//这个叫前置++,他会先进行+1计算,然后在使用原来的值++b;//此时值为:2//************************************************System.out.println(b++);//会输出:2System.out.println(b);//会输出:3


同样的减减也是

       int b=0;//这个叫后置--,他会先使用原来的值,然后再进行-1b--;//此时值为:-1//这个叫前置++,他会先进行-1计算,然后在使用原来的值--b;//此时值为:-2//************************************************System.out.println(b--);//会输出:-2System.out.println(--b);//会输出:-4

1.4关系运算符

运算符 计算结果
== true 或者 false
!= true 或者 false
> true 或者 false
< true 或者 false
<= true 或者 false
>= true 或者 false
int a = 10;
int b = 20;
// 注意:在Java中 = 表示赋值,要与数学中的含义区分
// 在Java中 == 表示相等
System.out.println(a == b); // false
//a是不是不等于b,是,逻辑上返回true
System.out.println(a != b); // true
System.out.println(a < b); // true
System.out.println(a > b); // false
System.out.println(a <= b); // true
System.out.println(a >= b); // false

注意:

计算机中是无法识别 0<a<50,必需要分开写,并且加上逻辑运算符符号

2.逻辑符号(重要)

符号 运算结果(boolean类型) 理解
&& true 或者 false 并且
true 或者 false

这里csd中||有特殊含有,打不出,就用图片代替了

2.1&&的语法结构:表达式 1 && 表达式 2

两真为真,一假全假

表达式1 表达式2 结果
真(true) 真(true) 真(true)
真(true) 假(false) 假(false)
假(false) 真(true) 假(false)
假(false) 假(false) 假(false)
int a = 1;
int b = 2;
System.out.println(a == 1 && b == 2); // 左为真 且 右为真 则结果为真
System.out.println(a == 1 && b > 100); // 左为真 但 右为假 则结果为假
System.out.println(a > 100 && b == 2); // 左为假 但 右为真 则结果为假
System.out.println(a > 100 && b > 100); // 左为假 且 右为假 则结果为假

2.2 || 的语法结构:表达式 1 || 表达式 2

全假为假,一真为真

表达式1 表达式2 结果
真(true) 真(true) 真(true)
真(true) 假(false) 真(true)
假(false) 真(true) 真(true)
假 (false) 假 (false) 假(false)
int a = 1;
int b = 2;
System.out.println(a == 1 || b == 2); // 左为真 且 右为真 则结果为真
System.out.println(a == 1 || b > 100); // 左为真 但 右为假 则结果也为真
System.out.println(a > 100 || b == 2); // 左为假 但 右为真 则结果也为真
System.out.println(a > 100 || b > 100); // 左为假 且 右为假 则结果为假

2.3 ! 的语法结构:** !表达式 **

真变假,假变真

int a = 1;
System.out.println(!(a == 1)); // a == 1 为true,取个非就是false
System.out.println(!(a != 1)); // a != 1 为false,取个非就是true

注意

  1. 对于 && , 如果左侧表达式值为 false, 则表达式结果一定是 false, 无需计算右侧表达式.
  2. 对于 || , 如果左侧表达式值为 true, 则表达式结果一定是 true, 无需计算右侧表达式.

3.位运算符(重要但是看实际需要)

3.1按位与 &

如果两个二进制位都是 1, 则结果为 1, 否则结果为 0

int a = 10;
int b = 20;
System.out.println(a & b);


3.2按位或 |

如果两个二进制位都是 0, 则结果为 0, 否则结果为 1

int a = 10;
int b = 20;
System.out.println(a | b);

3.3按位取反 ~

如果该位为 0 则转为 1, 如果该位为 1 则转为 0

int a = 0xf;//16进制
System.out.printf("%x\n", ~a)//printf 能够格式化输出内容, %x 表示按照十六进制输出

3.4按位异或 ^

如果两个数字的二进制位相同, 则结果为 0, 相异则结果为 1

int a = 0x1;
int b = 0x2;
System.out.printf("%x\n", a ^ b);//0

4.移位运算符

符号 实现逻辑
<< 最左侧位不要了, 最右侧补 0
>> 最右侧位不要了, 最左侧补符号位(正数补0, 负数补1)
>>> 最右侧位不要了, 最左侧补 0

一个二进制位的数的最左边一个位置是不用来计数的,通常叫做符号位代表一个数的正负情况
0:代表这个数为正
1:代表这个数为负

4.1 左移<<
这些图片的格子本该有32位,但是怕读者大人看不清,就用一个INT的位数来举例
向左移位时,丢弃的是符号位,因此正数左移可能会变成负数

int a = 0x10;
System.out.printf("%x\n", a << 1);


4.2 右移>>

最右侧位不要了, 最左侧补符号位(正数补0, 负数补1)

int a = 0x10;
System.out.printf("%x\n", a >> 1);


4.3 无符号右移 >>>
最右侧位不要了, 最左侧补 0

int a = 0x10;
System.out.printf("%x\n", a >>> 1)

注意

  1. 左移 1 位, 相当于原数字 * 2. 左移 N 位, 相当于原数字 * 2 的N次方.
  2. 右移 1 位, 相当于原数字 / 2. 右移 N 位, 相当于原数字 / 2 的N次方.

5.条件运算符(三目运算符)

表达式1 ? 表达式2 : 表达式3
表达式1 的值为 true 时, 整个表达式的值为 表达式2 的值
表达式1 的值为 false 时, 整个表达式的值为 表达式3 的值

// 求两个整数的最大值
int a = 10;
int b = 20;
int max = a > b ? a : b;
int Min = a < b ? a : b;

运算符小总结

  1. 在运算中为了不必要的歧异,我建议在复杂运算时最好加上(),以到达你想要的算数优先级

四、逻辑控制

1.if…else(常用)

1.1表达格式(三种)

  1. 小括号里面进行判断条件是否符合,正确执行语句

        if(布尔表达式){ 语句 }
    
  2. 在小括号里面进行条件判断,正确执行语句1,错误执行语句2

           if (布尔表达式) {  语句1 }else{语句2 }
    
  3. 表达式1正确,执行语句1,诺表达式1不正确,
    则去判断表达式2是否正确,正确则执行语句2,
    表达式2不正确,则去语句3。

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

外入:为了能将值能够通过键盘等工具,输入到计算机里面,java为此提供了一个方法Scanner。我们不需要懂的实现原理,只需要知道它的作用,和实现方法就行。这就是java的其中一个好处。

如何使用?

Scanner scanner=new Scanner(System.in);
//整型接收int l= scanner.nextInt();//提供整型输入
//浮点型接收float h= scanner.nextFloat();//提供一个浮点数输入
//字符串接收String p=scanner.next();//提供了一个字符串输入
//没有输入char类型的方法

将两者结合一下:
实例1:
题目:输入一个1~100的数字来代表一个学生的成绩,并给他或她给予这门课评价

分数在 [90, 100] 之间的,为优秀
分数在 [80, 90) 之前的,为良好
分数在 [70, 80) 之间的,为中等
分数在 [60, 70) 之间的,为及格
分数在 [ 0, 60) 之间的,为不及格

Scanner scanner=new Scanner(System.in);
//整型接收
int score = scanner.nextInt();//提供整型输入if(score >= 90){System.out.println("优秀");}else if(score >= 80 && score < 90){System.out.println("良好");}else if(score >= 70 && score < 80){System.out.println("中等");}else if(score >= 60 && score < 70){System.out.println("及格");}else if(score >= 0 && score < 60){System.out.println("不及格");}else{System.out.println("错误数据");}

实例2:
判断一个年份是否是闰年(什么是闰年?就是一般年份多天的年份),如何解题?
四年一闰、百年不闰、400年再闰
用年份除以4,没有余数的就是闰年,有余数的是平年,如果是世纪年(整百年)则是除以400。

Scanner scanner=new Scanner(System.in);
//整型接收
int year = scanner.nextInt();//输入年份if (year % 100 == 0) {//判断世纪闰年if (year % 400 == 0) {System.out.println("是闰年");} else {System.out.println("不是闰年");}
} else {//判断普通闰年if (year % 4 == 0) {System.out.println("是闰年");} else {System.out.println("不是闰年");}
}

2.switch…case(用的少)

2.1表达式

     switch(表达式){case 常量值1:{语句1;break;//终止语句}case 常量值2:{语句2;break;//终止语句}.....default:{内容都不满足时执行语句;break;//终止语句}}
  1. 先计算表达式的值
  2. 和case依次比较,一旦有响应的匹配就执行该项下的语句,直到遇到break时结束
  3. 当表达式的值没有与所列项匹配时,执行default

实例1
输入一个数(1~10)的数,判断它是星期几

Scanner scanner=new Scanner(System.in);
//整型接收
int day = scanner.nextInt();//输入日期switch(day) {case 1:System.out.println("星期一");break;case 2:System.out.println("星期二");break;case 3:System.out.println("星期三");break;case 4:System.out.println("星期四");break;case 5:System.out.println("星期五");break;case 6:System.out.println("星期六");break;case 7:System.out.println("星期日");break;default:System.out.println("这个数不在日期中");break;
}

注意:

  1. 多个case后的常量值不可以重复
  2. switch的括号内只能是以下类型的表达式:
    基本类型:byte、char、short、int,注意不能是long类型
    引用类型:String常量串、枚举类型

3.while(常用)

3.1语法格式

  1. 循环条件为 true, 则执行循环语句; 当条件不满足时为false,则结束循环.

                while(循环条件){循环语句;}
    

实例1
计算 1 ~ 100 的和

int n = 1;int result = 0;while (n <= 100) {result += n;n++;}System.out.println(num);//5050

实例2:
计算 5 的阶乘

int n = 1;
int result = 1;
while (n <= 5) {result *= n;n++;
}
System.out.println(num);//120

实例3
计算 1! + 2! + 3! + 4! + 5!的和

int num = 1;
int sum = 0;
// 外层循环负责求阶乘的和
while (num <= 5) {int factorResult = 1;int tmp = 1;
// 里层循环负责完成求阶乘的细节.while (tmp <= num) {factorResult *= tmp;tmp++;}sum += factorResult;num++;
}System.out.println("sum = " + sum);

注意:
循环内的条件一定要设置好,诺是没有设置好就会一直循环,直到程序吃完你的所有运算资源。然后崩溃。

3.2关键字beak:

break 的功能是让循环提前结束.

实例:找到 100 - 200 中第一个 3 的倍数

int num = 100;
while (num <= 200) {if (num % 3 == 0) {System.out.println("找到了 3 的倍数, 为:" + num);//102break;}num++;
}

3.3关键字 continue:

continue 的功能是跳过这次循环, 立即进入下次循环
实例
找到 100 - 200 中所有 3 的倍数

int num = 100;
while (num <= 200) {if (num % 3 != 0) {num++; continue;}System.out.println("找到了 3 的倍数, 为:" + num);num++;
}

4.for…(常用)

4.1语法格式

表达式1: 用于初始化循环变量初始值设置,在循环最开始时执行,且只执行一次
表达式2: 循环条件,满足条件,则继续循环,否则循环结束
表达式3: 循环变量变化方式

     for(表达式1;布尔表达式2;表达式3){表达式4;}

如何执行?
(1,2,3,4)—>(2,3,4)—>(2,3,4)—>(2,3,4)—>(2不满足条件)终止循环

实例1
计算 1 ~ 100 的和

int sum = 0;for (int i = 1; i <= 100; i++) {sum += i;
}System.out.println("sum = " + sum);5050

实例3
计算 1! + 2! + 3! + 4! + 5!的和

int sum = 0;
for (int i = 1; i <= 5; i++) {int tmp = 1;for (int j = 1; j <= i; j++) {tmp *= j;}sum += tmp;
}System.out.println("sum = " + sum);

注意:
和while循环一样,结束单趟循环用continue,结束整个循环用break

5.while…do(不常用)

5.1基本语法

  1. 先执行循环语句, 再判定循环条件,循环条件成立则继续执行,否则循环结束。

      do{循环语句;}while(循环条件);
    

实例

int num = 1;do {System.out.println(num);num++;
} while (num <= 10);

逻辑控制小总结

1.常用for,if,while,等逻辑控制
2.switch,case,break,要一起用
3.break终止当前循环,continue跳出这次循环

五、方法

在实际开发中,有一些代码是会被重复使用的。首先我们假设一个应用场景,假设有一个程序描述了一个计算器。一个计算器有乘,除,加,减,根号。现在我需要计算一个数字,先除,再乘,再除。那么我们就需要写入一个关于除法的代码,写一个乘法的代码,然后再写一个除法的代码。你看我们写了两次除法的代码。这样就太不方便了。

1.定义

所以在这是Java就引入了一个概念,方法,将一个代码用方法装起来,等需要用的时候就将,方法名放入带到要使用的代码中,通过这个方法名调用这个代码。

修饰符 返回值类型 方法名称([参数类型 形参 …]){
方法体代码;
[return 返回值];
}

2.模块化

public static int add(int x, int y) {
System.out.println("调用方法中 x = " + x + " y = " + y);
return x + y;
}
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("第一次调用方法之前");
int ret = add(a, b);
System.out.println("第一次调用方法之后");
System.out.println("ret = " + ret);
System.out.println("第二次调用方法之前");
ret = add(30, 50);
System.out.println("第二次调用方法之后");
System.out.println("ret = " + ret);
}

1.实参和形参的关系

看见括号中的参数吗?这个是参数,而参数分为形参和实参。

形参:就相当于add函数中的自变量x,用来接收add函数在调用时传递的值的。形参的名字可以随意取,对方法都没有任何影响,形参只是方法在定义时需要借助的一个变量,用来保存方法在调用时传递过来的值。
实参:通过实际参数可以更改变量的值的参数。

这里就不得不说一个东西。数据在内存中如何存储?
真实的存储中,存储一个数据会将一个唯一的地址与一个数据进行映射。形参就是将数据扔给add方法。而实参就是通过地址映射,来进行修改数据。此时add中对a进行改动,那么地址与之对应的数据就会改变

public static int getSum(int n){ // n是形参
return n / 2;
}
getSum(10); // 10是实参,在方法调用时,形参n用来保存10
getSum(100); // 100是实参,在方法调用时,形参n用来保存100

3.重载(重要后边有大用)

在Java中,如果多个方法的名字相同,参数列表不同,则称该几种方法被重载了。

为什么这样呢?我要去买菜,一个猪肉20块一斤,一斤白菜3.6块。那么问题来了。我要买一斤猪肉,3斤白菜。我要计算我要花多少钱。那么我就需要定义一个addMet(),addVegetable()然后总和。可是都是加法,为什么不定义一个add()只要中间的代码不同不就行了。

public class TestMethod {
public static void main(String[] args) {
add(1, 2); // 调用add(int, int)
add(1.5, 2.5); // 调用add(double, double)
add(1.5, 2.5, 3.5); // 调用add(double, double, double)
}
public static int add(int x, int y) {
return x + y;

注意:

  1. 方法名必须相同
  2. 参数列表必须不同(参数的个数不同、参数的类型不同、类型的次序必须不同)
  3. 与返回值类型是否相同无关

4.重写(重要后边有大用)

5.递归(重要,一种思维方式)

这种思想在数学和编程中非常有用,因为有些时候,我们遇到的问题直接并不好解决,但是发现将原问题拆分成其子问题之后,子问题与原问题有相同的解法,等子问题解决之后,原问题就迎刃而解了。

//计算阶乘
public static void main(String[] args) {
int n = 5;
int ret = factor(n);
System.out.println("ret = " + ret);
}
public static int factor(int n) {
if (n == 1) {
return 1;
}
return n * factor(n - 1); // factor 调用函数自身
}

具体实现过程,红色为调用,绿色为返回

注意:

  1. 将原问题划分成其子问题,注意:子问题必须要与原问题的解法相同
  2. 递归出口

方法小总结

  1. 修饰符(权限修饰符):public(公开)
  2. 返回值类型:如果方法有返回值,返回值类型必须要与返回的实体类型一致,如果没有返回值,必须写成void
  3. 方法名字:采用小驼峰命名
  4. 参数列表:如果方法没有参数,()中什么都不写,如果有参数,需指定参数类型,多个参数之间使用逗号隔开
  5. 方法体:方法内部要执行的语句
  6. 在java当中,方法必须写在类当中
  7. 在java当中,方法不能嵌套定义
  8. 在java当中,没有方法声明一说

六、数组(非常重要)

1.定义

数组:可以看成是相同类型元素的一个集合。在内存中是一段连续的空间。

数组类型 [] 数组名 = new 数组类型[数组长度];

数组类型 [] 数组名={元素,元素};

int[] array1 = new int[10]; // 创建一个可以容纳10个int类型元素的数组
double[] array2 = new double[5]; // 创建一个可以容纳5个double类型元素的数组
String[] array3 = new double[3]; // 创建一个可以容纳3个字符串元素的数组
//数组初始化
int[] array1 = new int[]{0,1,2,3,4,5,6,7,8,9};
double[] array2 = new double[]{1.0, 2.0, 3.0, 4.0, 5.0};
String[] array3 = new String[]{"hell", "Java", "!!!"};

如果数组中存储元素类型为引用类型,默认值为null

2.遍历

  1. 数组是一段连续的内存空间,因此支持随机访问,即通过下标访问快速访问数组中任意位置的元素
  2. 下标从0开始,介于**[0, N)**之间不包含N,N为元素个数,不能越界,否则会报出下标越界异常。
    原因是在之前再说如何存储时说过,计算机寻找数据是通过地址访问,而在数组中在你定义一个恒定大小长度的数组,在内存中就会开辟与数据类型相应大小的容量,一旦发现你寻找的数据通过下标寻找不在数组范围内就会出错(报错)。)

程序计数器 (PC Register): 只是一个很小的空间, 保存下一条执行的指令的地址

虚拟机栈(JVM Stack): 与方法调用相关的一些信息,每个方法在执行时,都会先创建一个栈帧,栈帧中包含有:局部变量表、操作数栈、动态链接、返回地址以及其他的一些信息,保存的都是与方法执行时相关的一些信息。比如:局部变量。当方法运行结束后,栈帧就被销毁了,即栈帧中保存的数据也被销毁了。

本地方法栈(Native Method Stack): 本地方法栈与虚拟机栈的作用类似. 只不过保存的内容是Native方法的局部变量. 在有些版本的 JVM 实现中(例如HotSpot), 本地方法栈和虚拟机栈是一起的

堆(Heap): JVM所管理的最大内存区域. 使用 new 创建的对象都是在堆上保存 (例如前面的 new int[]{1, 2,3} ),堆是随着程序开始运行时而创建,随着程序的退出而销毁,堆中的数据只要还有在使用,就不会被销毁。

方法区(Method Area): 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据. 方法编译出的的字节码就是保存在这个区域

int[] array = {1, 2, 3};
System.out.println(array[3]); // 数组中只有3个元素,
//下标一次为:0 1 2,array[3]下标越界

2.1遍历方法

通过循环遍历数组

int[]array = new int[]{10, 20, 30, 40, 50};
for(int i = 0; i < 5; i++){
System.out.println(array[i]);
}

注意:在数组中可以通过 数组对象.length 来获取数组的长度

int[]array = new int[]{10, 20, 30, 40, 50};
for(int i = 0; i < array.length; i++){
System.out.println(array[i]);
}

for循环的强化

int[] array = {1, 2, 3};
for (int x : array) {
System.out.println(x);
}

基本变量:基本数据类型创建的变量,称为基本变量,该变量空间中直接存放的是其所对应的值

引用类型变量:而引用数据类型创建的变量,一般称为对象的引用,其空间中存储的是对象所在空间的地址

方法参数为引用类型,这就可以通过地址改动或调用数组中的元素

public static void main(String[] args) {
int[] arr = {1, 2, 3};
func(arr);
System.out.println("arr[0] = " + arr[0]);
}
public static void func(int[] a) {
a[0] = 10;
System.out.println("a[0] = " + a[0]);
}

2.2Arrays方法

3.二维数组

数据类型[][] 数组名称 = new 数据类型 [行数][列数] { 初始化数据 };

int[][] arr = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}};

二维数组遍历

for (int row = 0; row < arr.length; row++) {for (int col = 0; col < arr[row].length; col++) {System.out.printf("%d\t", arr[row][col]);}System.out.println("");
}

其实就是一个特殊的一维数组。

数组小总结

1.数组是引用类型(通过地址寻找)
2.下标从0~数组长度-1
3.数组中元素类型与数组类型一致

七、类和对象

1. 定义(重要)

类是用来对一个实体(对象)来进行描述的,比如一个人(实体(对象)),但是一个人又有脖子(类),手(类),脚(类),眼睛(类)等,这样我们就对一个人进行了完整的刻画。当然人(对象)也是不同的。比如,我和你都是人,但是我们脖子或许有些不同。

1.1 类

主要描述该实体(对象)具有哪些属性(外观尺寸等)。
类中包含的内容称为类的成员。

属性主要是用来描述类的,称之为类的成员属性或者类成员变量。

方法主要说明类具有哪些功能,称为类的成员方法。

class PetDog {public String name;//名字
public String color;//颜色
// 狗的属性
public void barks() {
System.out.println(name + ": 旺旺旺~~~");
}
// 狗的行为
public void wag() {
System.out.println(name + ": 摇尾巴~~~");
}
}
  • 一般一个文件当中只定义一个类
  • main方法所在的类一般要使用public修饰
  • public修饰的类必须要和文件名相同
  • 不要轻易去修改public修饰的类的名称

1.2 对象

new 关键字用于创建一个对象的实例. 使用 . 来访问对象中的属性和方法. 同一个类可以创建多个实例.

简单而言就是,人不同,但描述人的方式是一样的。通过不同的实例化从而进行对不同人的描述。

class PetDog {public String name;//名字public String color;//颜色// 狗的属性public void barks() {System.out.println(name + ": 旺旺旺~~~");}// 狗的行为public void wag() {System.out.println(name + ": 摇尾巴~~~");}
}
public class Main{public static void main(String[] args) {PetDog dogh = new PetDog(); //通过new实例化对象dogh.name = "阿黄";dogh.color = "黑黄";dogh.barks();dogh.wag();PetDog dogs = new PetDog();dogs.name = "阿黄";dogs.color = "黑黄";dogs.barks();dogs.wag();}
}

2. this关键字(重要)

在实际运用中,会出现一个方法会传入多种数据的情况,但是每个传进去的值,一定不能拿错。为了确定每个传进去的值,就用this关键字。
具体问题是

  1. 形参名不小心与成员变量名相同
  2. 多个对象都在调用相同的函数,但是这这些函数中没有任何有关对象的说明,这些函数如何知道打印的是那个对象的数据呢?

具体作用:this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。

一个时间例子:

public class Date {public int year;public int month;public int day;public void setDay(int y, int m, int d){//多个数据传入后根本无法确定传入的值是什么。year = y;month = m;day = d;}public void printDate(){System.out.println(year + "/" + month + "/" + day);}public static void main(String[] args) {// 构造三个日期类型的对象 d1 d2 d3Date d1 = new Date();Date d2 = new Date();Date d3 = new Date();// 对d1,d2,d3的日期设置d1.setDay(2020,9,15);d2.setDay(2020,9,16);d3.setDay(2020,9,17);// 打印日期中的内容d1.printDate();d2.printDate();d3.printDate();}
}

正确写法

创建一个时间对象。

public class Date {public int year;public int month;public int day;public void setDay(int year, int month, int day){this.year = year;this.month = month;this.day = day;}public void printDate(){System.out.println(this.year + "/" + this.month + "/" + this.day);}
}

调用

public static void main(String[] args) {Date d = new Date();d.setDay(2020,9,15);d.printDate();
}

2.1 特点

  1. this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型
  2. this只能在成员方法中使用
  3. 在成员方法中,this只能引用当前对象,不能再引用其他对象
  4. this是成员方法第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this负责来接收

3. 构造方法(重要)

构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用一次。

3.1实现方式

  1. 名字与类名相同,没有返回值类型,设置为void也不行
  2. 一般情况下使用public修饰
  3. 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
public class Date {public int year;public int month;public int day;// 构造方法:public Date(int year, int month, int day){this.year = year;this.month = month;this.day = day;System.out.println("Date(int,int,int)方法被调用了");}public void printDate(){System.out.println(year + "-" + month + "-" + day);}public static void main(String[] args) {// 此处创建了一个Date类型的对象,并没有显式调用构造方法Date d = new Date(2021,6,9); // 输出Date(int,int,int)方法被调用了d.printDate(); // 2021-6-9}
}

3.2作用

构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间。

特点:

  1. 名字必须与类名相同
  2. 没有返回值类型,设置为void也不行
  3. 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每个人只能出生一次)
  4. 构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)(名字相同,参数列表不同,因此构成了方法重载)
  5. 如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的。
  6. 没有定义任何构造方法,编译器会默认生成一个不带参数的构造方法

对象空间被申请好之后,对象中包含的成员已经设置好了初始值,

数据类型 默认值
byte 0
char ‘\u0000’
short 0
int 0
long 0L
boolean false
float 0.0f
double 0.0
reference null

4. 封装

面向对象程序三大特性:封装、继承、多态。而类和对象阶段,主要研究的就是封装特性。何为封装呢?简单来说就是套壳屏蔽细节。

举个例子说明:
我们在使用手机时我们用户只管直接去使用,无需去理解这些具体功能是如何实现的。我只需要来用。但是对于设计者而言。他们需要去将这些功能进行实现,并将这些功能装起来,无需用户去理解功能实现,只需要他们会用就可以。

4.1包权限(重要)

范围 private default protected public
同一包中的同一类
同一包中的不同类 ×
不同包中的子类 × ×
不同包中的非子类 × × ×

public:可以理解为一个人的外貌特征,谁都可以看得到
default: 对于自己家族中(同一个包(同一个目录)中)不是什么秘密,对于其他人来说就是隐私了
private:只有自己知道,其他人都不知道

在面向对象体系中,提出了一个软件包的概念,即:为了更好的管理类,把多个类收集在一起成为一组,称为软件包。有点类似于目录。

可以使用 import语句导入包

import java.util.*;
public class Computer {private String cpu; // cpuprivate String memory; // 内存public String screen; // 屏幕String brand; // 品牌---->default属性public Computer(String brand, String cpu, String memory, String screen) {this.brand = brand;this.cpu = cpu;this.memory = memory;this.screen = screen;}public void Boot(){System.out.println("开机~~~");}public void PowerOff(){System.out.println("关机~~~");}public void SurfInternet(){System.out.println("上网~~~");}
}public class TestComputer {public static void main(String[] args) {Computer p = new Computer("HW", "i7", "8G", "13*14");System.out.println(p.brand); // default属性:只能被本包中类访问System.out.println(p.screen); // public属性: 可以任何其他类访问// System.out.println(p.cpu); // private属性:只能在Computer类中访问,不能被其他类访问}
}

通过import 导入我们需要的包。可以通过 * 号将整个包导入,也可以将这个符号改成具体的文件名。我更建议后者。因为这个符号代表者文件下面的全部文件。我们更建议显式的指定要导入的类名. 否则还是容易出现冲突的情况.

常见的包:

  1. java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
  2. java.lang.reflect:java 反射编程包;
  3. java.net:进行网络编程开发包。
  4. java.sql:进行数据库开发的支持包。
  5. java.util:是java提供的工具程序包。(集合类等) 非常重要
  6. java.io:I/O编程开发包。

4.2静态成员static(重要)

static修饰的成员变量,称为静态成员变量,静态成员变量最大的特性:不属于某个具体的对象,是所有对象所共享的。(俗称静态区)

  1. 不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中
  2. 既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问
  3. 类变量存储在方法区当中
  4. 生命周期伴随类的一生(即:随类的加载而创建,随类的卸载而销毁)
public class Student{private String name;private String gender;private int age;private double score;private static String classRoom = "Bit306";//看清楚,这里我用的是private修饰// ...
}
public class TestStudent {public static void main(String[] args) {System.out.println(Student.classRoom);}
}

这个代码会出现编译错误。

正确的是:

public class Student{private String name;private String gender;private int age;private double score;private static String classRoom = "Bit306";public static String getClassRoom(){return classRoom;}
}
public class TestStudent {public static void main(String[] args) {System.out.println(Student.getClassRoom());}
}

5.代码块

使用 {} 定义的一段代码称为代码块。

public class Main{
public static void main(String[] args) {{ //直接使用{}定义,普通方法块int x = 10 ;System.out.println("x1 = " +x);}int x = 100 ;System.out.println("x2 = " +x);}
}

实例代码块。构造代码块一般用于初始化实例成员变量。

 private String name;private String gender;private int age;private double score;public Student() {System.out.println("I am Student init()!");}
//实例代码块{this.name = "bit";this.age = 12;this.sex = "man";System.out.println("I am instance init()!");}

5.1 静态代码块(重要)

使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量。

public class Student{private String name;private String gender;private int age;private double score;private static String classRoom;
//实例代码块
{this.name = "李思";this.age = 12;this.gender = "men";System.out.println("你好!");
}
// 静态代码块
static {classRoom = "6班";System.out.println("你好同学!");
}
  1. 静态代码块不管生成多少个对象,其只会执行一次
  2. 静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
  3. 如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行合并
  4. 实例代码块只有在创建对象时才会执行

5.1同步代码块(多线程会出现)

等待我后续文章,这里不多解释,建议先看我后面的数据结构在来阅读这方面的文章.

6.内部类(重要)

A是外部类
B是内部类

可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。内部类也是封装的一种体现。(简单而言就是,在类中定义一个类,简称类中类)(调用方法在静态类中有体现)

public class A{class B{}
}
  1. 外部类中的任何成员都可以在实例内部类方法中直接访问
  2. 实例内部类所处的位置与外部类成员位置相同,因此也受public、private等访问限定符的约束
  3. 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名
    称.this.同名成员 来访问
  4. 实例内部类对象必须在先有外部类对象前提下才能创建
  5. 实例内部类的非静态方法中包含了一个指向外部类对象的引用
  6. 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。
public class A{
// 成员位置定义:未被static修饰 --->实例内部类public class B{}
// 成员位置定义:被static修饰 ---> 静态内部类static class C{}
public void func(){
// 方法中也可以定义内部类 ---> 局部内部类:几乎不用class D{}}
}

6.1静态内部类

被static修饰的内部成员类称为静态内部类

public class ClassA {private int a;static int b;public void methodA(){a = 10;System.out.println(a);}public static void methodB(){System.out.println(b);}// 静态内部类:被static修饰的成员内部类static class ClassB{public void methodInner(){// 在内部类中只能访问外部类的静态成员// a = 100; // 编译失败,因为a不是类成员变量b =200;// methodA(); // 编译失败,因为methodB()不是类成员方法methodB();}}public static void main(String[] args) {// 静态内部类对象创建 & 成员访问ClassA.ClassB Class = new ClassA.ClassB();Class.methodInner();}
}

6.2非静态/实例内部类

即未被static修饰的成员内部类。

 public class OutClass {private int a;static int b;int c;public void methodA(){a = 10;System.out.println(a);}public static void methodB(){System.out.println(b);}// 实例内部类:未被static修饰class InnerClass{int c;public void methodInner(){// 在实例内部类中可以直接访问外部类中:任意访问限定符修饰的成员a = 100;b =200;methodA();methodB();// 如果外部类和实例内部类中具有相同名称成员时,优先访问的是内部类自己的c = 300;System.out.println(c);// 如果要访问外部类同名成员时候,必须:外部类名称.this.同名成员名字OutClass.this.c = 400;System.out.println(OutClass.this.c);}}public static void main(String[] args) {
// 外部类:对象创建 以及 成员访问OutClass outClass = new OutClass();System.out.println(outClass.a);outClass.methodA();

实例内部类的访问

// 要访问实例内部类中成员,必须要创建实例内部类的对象
// 而普通内部类定义与外部类成员定义位置相同,因此创建实例内部类对象时必须借助外部类
// 创建实例内部类对象OutClass.InnerClass innerlass1 = new OutClass().new InnerClass();
// 上述语法比较怪异,也可以先将外部类对象先创建出来,然后再创建实例内部类对象OutClass.InnerClass innerClass2 = outClass.new InnerClass();innerClass2.methodInner();
}

6.3匿名内部类(不着急他的主要途径是在抽象类中)

类和对象的小总结

1.类就是描述物体的一种集合,类中定义的方法以及成员是具体描述这个物体的固有属性(称其为对象)(如动物这个大类他是一个抽象的描述,并不具体,而动物有很多他们都有不同的名字,体型,身高,叫声,比如狗,猫,鸟,老虎…这些动物的描述方式各有不同)

2.用{}包裹的就是代码块,用static修饰的是静态代码块

3.内部类就是通过在一个类中再次定义一个的方式,通常分为非静态内部类,静态内部类(用static修饰的静态的内部类。)

4.内部类调用通常:(非静态内部类 ) **外部类.内部类 xxx=外部类.new 内部类();**进行实例化。(静态内部类)**外部类.内部类 xxx=new 外部类.内部类();**进行实例化。

八、继承和多态(重要)

对于java来说,最重要的就是面对对象,而如何体现这个,在其中三个概念极为重要,封装、继承、多态而无论考试还是面试通常都会考察这几个概念及其原理用法。

1.继承

面向对象思想中提出了继承的概念,专门用来进行共性抽取,实现代码复用。在实际使用类和对象的过程中,会出现的几个问题,比如我们定义了一个猫和狗的类。它们有着共同的一些性质,或者说是行为。比如他们都是动物,都有名字,也都会吃饭。我们在描述它们时,就会将这些行为或者属性通过方法或者成员进行描述。这样我们就发现了他们,在某些情况下,代码是重复的。为了避免代码复写,就将一个类的共有属性进行封装。在出现这个类的子类时(什么是子类?比如“动物”他就父类,而“动物”下面会细分其他“动物”比如“狗”,那么“动物”就是“狗”的父类,“狗”是“动物”的子类),我们只需要描述,这个子类特有的特点就好。而他们的共同特点,可以通过继承他的父类的公共方法进行使用。

1.1 定义

继承(inheritance)机制:是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加新功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构, 体现了由简单到复杂的认知过程。继承主要解决的问题是:共性的抽取,实现代码复用。

父类:又叫基类,也叫超类
子类:又叫派生类


语法:

修饰符 class 子类 extends 父类 {// ...
}

父类

// Animal.javapublic class Animal{String name;int age;public void eat(){System.out.println(name + "正在吃饭");}public void sleep(){System.out.println(name + "正在睡觉");}
}

子类

// Dog.java//子类
public class Dog extends Animal{void bark(){System.out.println(name + "汪汪汪~~~");}
}

测试类

// TestExtend.java
public class TestExtend {public static void main(String[] args) {Dog dog = new Dog();// dog类中并没有定义任何成员变量,name和age属性肯定是从父类Animal中继承下来的System.out.println(dog.name);System.out.println(dog.age);// dog访问的eat()和sleep()方法也是从Animal中继承下来的dog.eat();dog.sleep();dog.bark();}
}

在子类方法中 或者 通过子类对象访问成员时:

成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找。

  1. 如果访问的成员变量子类中有优先访问自己的成员变量
  2. 如果访问的成员变量子类中无则访问父类继承下来的,如果父类也没有定义,则编译报错。
  3. 如果访问的成员变量与父类中成员变量同名,则优先访问自己的
  4. 成员方法没有同名时,在子类方法中或者通过子类对象访问方法时,则优先访问自己的,自己没有时再到父类中找,如果父类中也没有则报错。
  5. 通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到则访问,否则编译报错。
  6. 通过派生类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用方法适传递的参数选择合适的方法访问,如果没有则报错;

1.2 关键字super

问题:如果子类中存在与父类中相同的成员时,那如何在子类中访问父类相同名称的成员呢?没错,通过super关键字。与this关键字相似,不过前者是声明调用的是父类中的方法。

父类

public class Base {int a;int b;public void methodA(){System.out.println("Base中的methodA()");}public void methodB(){System.out.println("Base中的methodB()");}
}

子类

public class Derived extends Base{int a; // 与父类中成员变量同名且类型相同char b; // 与父类中成员变量同名但类型不同// 与父类中methodA()构成重载public void methodA(int a) {System.out.println("Derived中的method()方法");}// 与基类中methodB()构成重写(即原型一致,重写后序详细介绍)public void methodB(){System.out.println("Derived中的methodB()方法");}public void methodC(){// 对于同名的成员变量,直接访问时,访问的都是子类的a = 100; // 等价于: this.a = 100;b = 101; // 等价于: this.b = 101;// 注意:this是当前对象的引用// 访问父类的成员变量时,需要借助super关键字// super是获取到子类对象中从父类继承下来的部分super.a = 200;super.b = 201;// 父类和子类中构成重载的方法,直接可以通过参数列表区分清访问父类还是子类方法methodA(); // 没有传参,访问父类中的methodA()methodA(20); // 传递int参数,访问子类中的methodA(int)// 如果在子类中要访问重写的基类方法,则需要借助super关键字methodB(); // 直接访问,则永远访问到的都是子类中的methodA(),父类的无法访问到super.methodB(); // 访问父类的methodB()}
}

构造方法

子类对象构造时,需要先调用基类构造方法,然后执行子类的构造方法

父类构造

public class Base {public Base(){System.out.println("Base()");}
}

子类构造

public class Derived extends Base{public Derived(){super();// 注意子类构造方法中默认会调用基类的无参构造方法:super(),// 用户没有写时,编译器会自动添加,而且super()必须是子类构造方法中第一条语句,// 并且只能出现一次System.out.println("Derived()");}
}
public class Test {public static void main(String[] args) {Derived d = new Derived();}
}结果打印:Base()Derived()

super与this的区别
相同点:

  1. 都是Java中的关键字
  2. 只能在类的非静态方法中使用,用来访问非静态成员方法和字段
  3. 在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在

构造方法

不同点:

  1. this是当前对象的引用,当前对象即调用实例方法的对象,super相当于是子类对象中从父类继承下来部分成员的引用
  2. 在非静态成员方法中,this用来访问本类的方法和属性super用来访问父类继承下来的方法和属性
  3. 在构造方法中:this()用于调用本类构造方法,super(…)用于调用父类构造方法,两种调用不能同时在构造方法中出现
  4. 构造方法中一定会存在super(…)的调用,用户没有写编译器也会增加,但是this(…)用户不写则没有

执行优先分析(重要)

class Person {public String name;public int age;public Person(String name, int age) {this.name = name;this.age = age;System.out.println("Person:构造方法执行");}{System.out.println("Person:实例代码块执行");}static {System.out.println("Person:静态代码块执行");}}
class Student extends Person{public Student(String name,int age) {super(name,age);System.out.println("Student:构造方法执行");}{System.out.println("Student:实例代码块执行");}static {System.out.println("Student:静态代码块执行");}
}
/*
Person:静态代码块执行
Student:静态代码块执行
Person:实例代码块执行
Person:构造方法执行
Student:实例代码块执行
Student:构造方法执行
*/
  1. 父类静态代码块优先于子类静态代码块执行,且是最早执行
  2. 父类实例代码块和父类构造方法紧接着执行
  3. 子类的实例代码块和子类构造方法紧接着再执行
  4. 第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行

继承的方式种类
这个图是我从其他地方摘抄来的。以问过作者了,主要是这个图确实好用。

1.3 关键字 final

final关键可以用来修饰变量、成员方法以及类。

1.修饰变量
修饰变量或字段,表示常量(即不能修改)

final int a = 10;
a = 20; // 编译出错

2.修饰类
表示此类不能被继承

final public class Animal {

}
public class Bird extends Animal {

}

3.修饰方法
表示该方法不能被重写

2.多态

**通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同 的状态。**比如动物,它有猫这个子类,也有狗这个子类,但是他们吃的东西不同,猫吃猫粮,狗吃狗粮,在父类中出现吃这个动作。而子类将这些具象化了,呈现了不同类型不同状态的形式。(多态)

2.1定义

  1. 必须在继承体系下
  2. 子类必须要对父类中方法进行重写(及重写就是对父类方法的重新构写)
  3. 通过父类的引用调用重写的方法
public class Animal {String name;int age;public Animal(String name, int age){this.name = name;this.age = age;}public void eat(){System.out.println(name + "吃饭");}}
public class Cat extends Animal{public Cat(String name, int age){super(name, age);}@Overridepublic void eat(){System.out.println(name+"吃鱼~~~");}}}

2.2 重写

重写(override):也称为覆盖。重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等的实现过程进行重新编写, 返回值和形参都不能改变。也就是说子类能够根据需要实现父类的方法。
规则:

  1. 子类在重写父类的方法时,一般必须与父类方法原型一致: 返回值类型 方法名 (参数列表) 要完全一致
  2. 被重写的方法返回值类型可以不同,但是必须是具有父子关系的
  3. 访问权限不能比父类中被重写的方法的访问权限更低。如果父类方法被public修饰,则子类中重写该方法就不能声明为 protected
  4. 父类被static、private修饰的方法、构造方法都不能被重写。
  5. 重写的方法, 可以使用 @Override 注解来显式指定. 有了这个注解能帮我们进行一些合法性校验.
区别 重写(override) 重载(override)
参数列表 一定不能修改 必须修改
返回类型 一定不能修改【除非可以构成父子类关系】 可以修改
访问限定符 一定不能做更严格的限制 可以修改

重写:方法名和参数必须一致

重载:方法名相同,参数不同

重载

2.3 向上/向下转型

向上转型:
向上转型:实际就是创建一个子类对象,将其当成父类对象来使用。

父类类型 对象名 = new 子类类型()

Animal animal = new Cat("将军");

向下转型:
将父类引用再还原为子类对象,即向下转换。

public class TestAnimal {public static void main(String[] args) {Cat cat = new Cat("将军");Dog dog = new Dog("虞姬");// 向上转型Animal animal = cat;animal.eat();animal = dog;animal.eat();if(animal instanceof Cat){cat = (Cat)animal;cat.mew();}if(animal instanceof Dog){dog = (Dog)animal;dog.bark();}
}

注意:
向下转型用的比较少,而且不安全,万一转换失败,运行时就会抛异常。Java中为了提高向下转型的安全性,引入了 instanceof ,如果该表达式为true,则可以安全转换。

继承和多态的小总结

1.多态能够降低代码的 “圈复杂度”(形容代码的复杂程度,一般if-else不超过10), 避免使用大量的 if - else
2.多态可扩展能力更强
3.向上转型用的更多也更安全,向下转型,会横跨两个子类,可能会出现跨类调用

九、抽象类与接口(重要)

如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类,他没有具体的实现方法,只提供了一个方法或成员

1.抽象类

abstract 修饰称为抽象类,抽象类中被 abstract 修饰的方法称为抽象方法,抽象方法不用给出具体的实现体。

// 抽象类:被abstract修饰的类
public abstract class Shape {
// 抽象方法:被abstract修饰的方法,没有方法体abstract public void draw();abstract void calcArea();
// 抽象类也是类,也可以增加普通方法和属性public double getArea(){return area;}protected double area; // 面积
}

抽象类

特点:

  1. 抽象类不能直接实例化对象
  2. 抽象方法不能是 private 的
  3. 抽象方法不能被final和static修饰,因为抽象方法要被子类重写
  4. 抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用 abstract 修饰
  5. 抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类
  6. 抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量

2.接口

接口可以看成是:多个类的公共规范,是一种引用数据类型。接口你可理解成父类也就是父类,接口,可以理解为一类东西,只是运用的范围不同而已。

抽象类---->接口==(约等于)父类

2.1定义

接口的定义格式与定义类的格式基本相同,将class关键字换成 interface 关键字,就定义了一个接口。

public interface 接口名称{
// 抽象方法// public abstract 是固定搭配,可以不写public abstract void method1(); public void method2();abstract void method3();// 注意:在接口中上述写法都是抽象方法,跟推荐方式4,代码更简洁void method4();}

2.2 实现

接口不能直接使用,必须要有一个"实现类"来"实现"该接口,实现接口中的所有抽象方法。

子类和父类之间是extends 继承关系,类与接口之间是 implements 实现关系。

// USB接口
public interface USB {void openDevice();void closeDevice();
}
// 鼠标类,实现USB接口
public class Mouse implements USB {@Overridepublic void openDevice() {System.out.println("打开鼠标");}
}

接口

抽象类与接口的小总结

  1. 接口类型是一种引用类型,但是不能直接new接口的对象
  2. 接口中每一个方法都是public的抽象方法, 即接口中的方法会被隐式的指定为 public abstract(只能是public abstract,其他修饰符都会报错)
  3. 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现
  4. 重写接口中方法时,不能使用默认的访问权限
  5. 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量
  6. 接口中不能有静态代码块和构造方法
  7. 接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class
  8. 如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类
  9. jdk8中:接口中还可以包含default方法。
  10. 接口可以继承一个接口, 达到复用的效果. 使用 extends 关键字.(增加了扩展性)

其实对于接口和类,java自带的库中有很多好用的方法。这里先不赘述,在文件末尾,我会对这些进行总结(用链接的方式)(就复习而言这些足以)

十、异常(重要)

在Java中,将程序执行过程中发生的不正常行为称为异常。

1.常见类型

1.算术异常

System.out.println(10 / 0);

java.lang.ArithmeticException

2.数组越界异常

int[] arr = {1, 2, 3};
System.out.println(arr[100]);

java.lang.ArrayIndexOutOfBoundsException

3.空指针异常

int[] arr = null;
System.out.println(arr.length);

java.lang.NullPointerException

  1. Throwable:是异常体系的顶层类,其派生出两个重要的子类, Error 和 Exception
  2. Error:指的是Java虚拟机无法解决的严重问题,比如:JVM的内部错误、资源耗尽等,典型代表:StackOverflowError和OutOfMemoryError,一旦发生回力乏术。
  3. Exception:异常产生后程序员可以通过代码进行处理,使程序继续执行。

2.实现

抛出异常

public static int getElement(int[] array, int index){if(null == array){//抛出异常throw new NullPointerException("传递的数组为null");}if(index < 0 || index >= array.length){//抛出异常throw new ArrayIndexOutOfBoundsException("传递的数组下标越界");}return array[index];
}
public static void main(String[] args) {int[] array = {1,2,3};getElement(array, 3);
}

捕获异常:

语法格式:
修饰符 返回值类型 方法名(参数列表) throws 异常类型1,异常类型2…{
}

try-catch捕获并处理

 语法格式:
try{// 将可能出现异常的代码放在这里
}catch(要捕获的异常类型 e){// 如果try中的代码抛出异常了,此处catch捕获时异常类型与try中抛出的异常类型一致时,或者是try中抛出异常的父类时,就会被捕获到// 对异常就可以正常处理,处理完成后,跳出try-catch结构,继续执行后序代码
}[catch(异常类型 e){// 对异常进行处理
}finally{// 此处代码一定会被执行到
}]// 后序代码// 当异常被捕获到时,异常就被处理了,这里的后序代码一定会执行// 如果捕获了,由于捕获时类型不对,那就没有捕获到,这里的代码就不会被执行

异常的小总结

  1. throws必须跟在方法的参数列表之后
  2. 声明的异常必须是 Exception 或者 Exception 的子类
  3. 方法内部如果抛出了多个异常,throws之后必须跟多个异常类型,之间用逗号隔开,如果抛出多个异常类型具有父子关系,直接声明父类即可。
  4. try块内抛出异常位置之后的代码将不会被执行
  5. 如果抛出异常类型与catch时异常类型不匹配,即异常不会被成功捕获,也就不会被处理,继续往外抛,直到JVM收到后中断程序----异常是按照类型来捕获的
  6. 写程序时,有些特定的代码,不论程序是否发生异常,都需要执行,比如程序中打开的资源:网络连接、数据库连接、IO流等,在程序正常或者异常退出时,必须要对资源进进行回收。另外,因为异常会引发程序的跳转,可能导致有些语句执行不到,finally就是用来解决这个问题的。

十一、其他文章接口

1.String方法(重要,对于操作字符串有巨大的帮助)

文章链接

2.java常用的接口及其方法(包含拷贝,比较,排序,构造器)

文章链接

3.初阶数据结构

3.1 顺序表:ArrayList

文章链接

3.2 链表:LinkedList

文章链接

3.3 栈:Stack

文章链接

3.4 队列:Queue

文章链接

3.5 二叉树:Tree

文章链接

3.6 优先级队列:PriorityQueue(堆排序)

文章链接

3.7 Map和Set

HashMap和HashSet,TreeMap和TreeSet
文章链接

4. 排序(7种方式)

4.1 插入排序(两种)

4.2 选择排序(两种)

4.3 快速排序

4.4 堆排序

里面有堆排序的实现和逻辑
文章链接

4.5 归并排序

5.多线程

文章链接

6.网络编程

7.HTML

8.数据库Mysql

文章链接

总结

这样不必担心对于复习考试而言绰绰有余。大家诺觉得有用可以收藏一波,等待后续对于数据结构,以及其他相关的文章。我会尽量讲的通俗讲清楚。代码考试需要大家去刷题,推荐一个小白刷题网站牛课网。(实测非常好用,大部分互联网公司都在用它招聘)

半小时复习java全内容相关推荐

  1. 半小时实现Java手撸Http协议,爽!!(附完整源码,建议收藏)

    大家好,我是冰河~~ 很多小伙伴跟我说,学习网络太难了,怎么办?其实很多技术都是相通的,只要你理解了技术的本质,你自己都可以实现它.这不,冰河就趁着周末,只用了几个Java类就简单的实现了Http协议 ...

  2. 用Python写了个金融数据爬虫,半小时干了全组一周的工作量

    最近,越来越多的研究员.基金经理甚至财务会计领域的朋友,向小编咨询:金融人需要学Python么? 事实上在2019年,这已经不是一个问题了.Python已成为国内很多顶级投行.基金.咨询等泛金融.商科 ...

  3. java resume过时方法_面试官没想到,一个 Java 线程生命周期,我可以扯半小时

    面试官:你不是精通 Java 并发吗?从基础的 Java 线程生命周期开始讲讲吧. 好的,面试官.吧啦啦啦... 如果要说 Java 线程的生命周期的话,那我觉得就要先说说操作系统的线程生命周期 因为 ...

  4. java 前端工作内容_java前端、java后端、java全栈工作主要内容是什么?哪个薪资高?...

    摘要 最近,听了一场关于java全栈工程师职位的简介说明,里面很清楚的说明了一下前端,后端,全栈都是做什么工作的.其实,想做这个行业,就应该了解职能以及技能需求,这样学习才能更高效.我知道一些刚刚入行 ...

  5. java打开android_解决android studio 打开java文件 内容全变了的问题

    问题描述: 某天打开项目的activity的java文件界面突然变成下面这样了,但是用Notepad++打开代码什么的都正常,不知道什么原因造成的 解决办法 使用notepad++打开java文件,随 ...

  6. java 半小时_java获取当前时间加半小时之后的时间

    java获取当前时间加半小时之后的时间: 1.获取当前时间,获取到的时间类型是long类型的,单位是毫秒 long currentTime = System.currentTimeMillis() ; ...

  7. 怎么判断日出时间早晚_珠海最全防堵攻略,知道这些上班时间或缩短半小时!有大数据分析!...

    谁都希望开车出门一脚油门,畅快淋漓,基本不塞车.但是随着城市的不断成长发展和机动车持续增加,交通拥堵又是客观存在.如何尽可能不受堵车之苦呢?一个有效的方法便是"错峰出行".那么,如 ...

  8. Java LocalDateTime给当前时间加半小时

    前言 现在有这样一个需求,需要将当前时间加上半小时返回给前端,在Java8之后推荐用LocalDateTime来替换Date,它提供了丰富的方法给我们来调用,那我们来实现一下 实现 如图所示,我们使用 ...

  9. java抽奖程序头像_半小时撸一个抽奖程序

    需求总是很紧急,昨天正在开会收到人力需求,有时间做个抽奖吗?(now 下午四点12,年会五点开始.)还没能等我拒绝,人事又补了一句做不出来我们就不抽奖了,我擦瞬间感觉要是搞不出来会被兄弟们捅死的节奏, ...

最新文章

  1. spring -- 自定义注解
  2. 解决npm下载包失败的问题
  3. ubuntu共享usb接口给虚拟机_如何在虚拟机的Ubuntu12.04中使用外部USB设备
  4. Aspose.Word 的常见使用(不用模板创建)
  5. 服务器cpu_服务器CPU与GPU协同运算加速三巨头竞争
  6. aptitude_PHP Numbers Aptitude问题与解答
  7. Bootstrap 组件之 Nav
  8. 电力企业计量生产需求系统解决方案
  9. Android TTS 初体验
  10. ANN 神经网络介绍
  11. CentOS安装QQ2012
  12. python 下标 遍历列表_Python中遍历列表中元素的操作
  13. java js 汉字对应拼音码,五笔码转换
  14. 反脆弱性—露天广场与办公楼
  15. C语言-求一元二次方程的解-你是否会了呢?
  16. matlab景深合成算法,关于景深合成,你想知道的都在这儿!
  17. 一个超好看的音乐网站设计与实现(HTML+CSS)
  18. html控制台随机数取整,获取随机数、浮点数取整方法
  19. 『paddle』paddleclas 学习笔记:分类预训练模型选择
  20. 如何做一个基于JAVA房产中介预约看房系统毕业设计毕设作品(springboot框架)

热门文章

  1. android 上下左右滑动的表格,适用小程序的表格table,冻结行,冻结列,可左右,上下滑动...
  2. cv2.VideoCapture(0)无法打开usb摄像头问题
  3. Linux常用命令之su 、sudo
  4. Angular教程英雄之旅版本踩坑记录
  5. mmdetection小技巧(强烈推荐 逐步完善中)
  6. python用Win32com连接excel与CAD实现自动绘图
  7. 基于深度学习的医学图像分割学习笔记(十一)nnU-net
  8. Ventuz打包vpr显示鼠标图标设置
  9. 2023计算机毕业设计选题推荐 - 计算机毕业设计题目大全
  10. riscv 启动流程分析