Java常用类
1、学前碎碎念
TIOBE 编程语言排行
什么是Java
Java能干什么
课程概述
如何更好更高效的学习Java
为什么培训出来的学生就要低人一等呢?只要技术好,功底扎实,包装一下怎么了
2、Java预科阶段
走进计算机
- 论博客的重要性
⚪博客,英文名为Bolg,正式网络名为网络日记
- 什么是计算机
-
硬件及冯诺依曼结构
-
软件及软件开发
-
常用快捷键和Dos命令
Alt+F4 :关闭当前窗口 Win+R :打开运行 Shift+Delete :永久删除 Win+E :打开我的电脑 CTRL+Shift+Esc :打开任务管理器
打开CMD的方式 在任意的文件夹下,按住Shift键 + 鼠标右键,在此处打开命令行窗口 资源管理器的地址前面加上cmd 路径 # 常用的Dos命令 # 盘符切换 D: # 查看当前目录下所有目录 dir # 切换目录 cd /d D:\BaiduNetdiskDownload cd .. 上一层 # 清理屏幕 cls # 退出终端 exit # ipconfig # calc :打开计算器 # mspaint :打开画图工具 # notepad :新建并打开一个记事本 # 鼠标右键是粘贴 # 创建文件夹 md test # 创建文件 cd>a.txt # 删除文件 del a.txt # 删除文件夹 rd luoli
-
计算机语言发展史
-
第一代语言:机器语言--二进制:010101,直接输入给计算机使用,不经过任何的转换
-
汇编语言:指令代替二进制
-
高级语言:
java、c、c++ 面向过程(C语言)和面向对象(C++和java) 摩尔定律 18个月单位体积晶体管数量增加一倍
3、Java入门
01. Java帝国的诞生
02. Java特性和优势
03. Java三大版本
- JavaSE:标准版 (桌面程序、控制台开发)基础
- JavaME:嵌入式开发(手机、小家电)
- JavaEE:企业级开发(web端、服务器开发)发展学习就业
04. JDK JRE JVM
- JVM:Java虚拟机,因为有了JVM,使得Java得以拥有强大的可移植性
- JRE:Java运行环境,包含JVM
- JDK:在JRE的基础上增加了一些工具
05. Java安装卸载
卸载JDK
- 删除java安装目录
- 删除JAVA_HOME
- 删除path下关于Java的目录
- cmd命令行使用Java -version测试
安装JDK
-
百度搜索JDK8,找到下载地址Oracle
-
下载电脑对应版本
-
记住安装的路径
-
配置环境变量
- 我的电脑--》属性--》高级系统设置--》环境变量
- 系统变量--》新建系统变量:名 JAVA_HOME 值 D:\Idea\environment\JDK1.8
- PATH--》新建--》%JAVA_HOME%\bin--》新建--》%JAVA_HOME%\jre\bin
-
测试JDK是否安装成功
cmd-->java -version
打开windows放大镜:win加+
HelloWorld
public class hello{ public static void main(String[] args){ System.out.print("我爱你罗丽"); } }
- 新建一个后缀名为java的文件
- shell窗口进入该文件所在的文件夹
- 编译: javac hello.java 先将其编译成.class后缀的字节码文件
- 运行class文件: java hello (注意无.class)控制台上输出内容
- 文件名和类名必须保持一致
Java程序运行机制
- 编译型:C语言、C++直接整体编译成程序可执行文件,在程序上运行速度快
- 解释型:边输入边解释,更新及时
Java文件是先编译成.class字节码文件,再去解释给系统执行
IDEA安装
4、Java基础
1.注释
//单行注释 只能注释一行文字
/*多行注释*/ 可以注释多行文字
/** 文档注释,可以带有功能的注释,比如@discription 描述 @author 作者 */
2.标识符和关键字

- 所有的标识符都应该以字母(A-Z或者a-z)、美元符号($)、或者下划线(_)开始
- 首字符之后可以是字母(A-Z或者a-z)、美元符号($)、或者下划线(_)和数字组合
- 不能使用关键字作为变量名或者方法名
- 标识符是大小写敏感的
- 可以使用中文命名,但一般不建议使用
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
//试一下这个注释的撒
String 王者荣耀 = "永恒钻石";
System.out.println(王者荣耀);
//大小写敏感
/*所有的标识符都应该以字母(A-Z或者a-z)、美元符号($)、或者下划线(_)开始
*/
String Man = "xinxin";
String man = "luoli";
String $man = "哥哥";
String _girl = "宝宝";
}
}
3.数据类型
-
强类型语言
- 要求变量的使用要严格符合规定,所有变量必须先定义后才能使用
-
弱类型语言
-
Java数据类型分为两大类
- 基本类型
//八大基本类型--从小到大 整数类型: byte b = 127 short s = 32767 int i = 2147483647 long l = 999666L 浮点类型:(小数) float f = 1.2 double d = 3.1415926 字符类型char: char c = '我' boolean类型: boolean b = true false
- 引用类型
字节
- 位(bit):计算机内部储存的最小单位,1=1位
- 字节(byte):计算机中数据处理的基本单位,大写B表示
- 1B字节=8bit位
- 字符:指计算机中使用的字母、数字、字和符号
- 1bit=1位
- 1Byte表示一个字节 1B=8b
- 1024B=1KB
- 1024KB=1M
- 1024M=1G
数据类型扩展以及面试
为什么你眼睛看到的东西,在程序运行后他就是不一样
- 十进制、八进制0、十六进制0X
int i1 = 10;
int i2 = 010; //八进制0
int i3 = 0X10; //十六进制0X
System.out.println(i1);
System.out.println(i2);
System.out.println(i3);
- 最好不用使用两个浮点数进行比较,因为浮点数是一个大约数,它表示的事接近但不等于,比较需要用到自定义类BigDecimal数学工具类
float f = 1.323212213f; //输出1.3232123是一个离散数,约数,接近但不等于,不精确需要后续用到一个自定义类BigDecimal数学工具类
System.out.println(f);
double d = 1.323212213;
System.out.println("---------");
System.out.println(f == d);
//结果事不等于
- 所有的字符本质上还是数字 0-65536
int i = 65;
System.out.println((char)i);
char c = '中';
System.out.println((int)c);
//所有的字符本质上还是数字 0-65536
//U0000-UFFFF
- 高级boolean,一般在判断语句里边不用==了,而是用默认值
boolean flag = false;
if (flag)
System.out.println("xxxxxxx");
else System.out.println("vvvvvvvv");
- 两个String类型和类里定义的String类型作比较也不同,因为在内存中不是同一块儿区域
String s1 = "hello,world";
String s2 = "hello,world";
System.out.println(s1 == s2);
String s3 = new String("hello,world");
String s4 = new String("hello,world");
System.out.println(s3 == s4);
类型转换
- 强制转换:(类型)变量名 高-->低
- 自动转换:低-->高
低---------------->高
byte,short,char-->int-->long-->float-->double
注意:字符'c'可以直接转成short=99,但成变量时就不支持自动转换了,但s"23456"却不可以直接转成char,所以理论上他俩都需要强转
//测试short类型与char类型谁高谁低,都占2字节
short s = 23456;
char c1 = (char)s;
short s1 = 'c';
//short s2 = c1;
System.out.println(c1);
System.out.println(s1);
//两个类型都需要强制转换
注意点:
-
因为布尔类型底层是位存储不是字节,所以不能对布尔值进行转换
-
不能对对象类型瞎转,
比如整数类型转引用类型 -
高容量转低容量时需要进行强制转换,反之则自动转换
-
转换的时候要注意存在内存溢出和精度问题(直接丢掉小数点后的东西)
int i = 128; byte b = (byte)i; System.out.println("int(大)转byte(小)为强制转"+b); System.out.println(i); double d = i; System.out.println("int(小)转double(大)为自动转"+d); System.out.println((int)23.8); System.out.println((int)23.6789f);
-
char和int:(字节码底层本质就是数字)
char c = 'a'; int c2 = c+1; System.out.println(c2); System.out.println((char)c2);
-
操作大数的时候,要注意溢出问题(JDK7新特性,数字之间可以用下划线分割int i = 100_0000)
int money = 10_0000_0000; int year = 20; long big1 = money*year;//在转换成long之前就已经内存溢出了,所以需要先转用long*int System.out.println(big1); long big2 = (long)money*year; System.out.println(big2); long l = 100_0000_0000L; //尽量用大写L
变量、常量、作用域
-
变量
-
变量是什么:就是可以变化的一块内存区域量
-
Java是一种强类型语言,每个变量都必须声明其类型。
-
Java变量是程序中最基本的存储单元,其要素包括变量类型,变量名和作用域。
type varName = value ,varName = value; 数据类型 变量名 = 值;可以用都好隔开赖生明多个同类型的变量 int a1 = 1,a2=2,c3=3;注意事项:
-
注意事项 :
- 每个变量都有类型,类型可以是基本类型,也可以是引用类型。
- 变量名必须是合法的标识符
- 变量声明是将完整的语句,因此每一个声明都必须以分号结束。
-
变量的命名规范
- 所有的变量、方法、类名要见名知意
- 类成员变量和局部变量:首字母小写和驼峰命名
- 常量:大写字母和下划线:MAX_VALUE
- 类名:首字母大写和驼峰命名原则:GoodMan
- 方法名:首字母小写和驼峰命名:myAss()
-
-
作用域
- 类变量:关键修饰符static,这个变量是加载在类里边跟随类的,作用域为全类。自动有初始值(整数型:0、0.0 其他引用类型默认都是null)
- 实例变量:声明在类里面方法外的,使用时需要new()该方法.出来,作用域全类(但使用时需要new())自动有初始值
- 局部变量:声明在方法里边的,作用域该方法内部,不支持跨方法使用,同名时优先显示本方法的变量
//属性:变量、类变量 static final String THING = "爱情"; static String nameGirl = "罗丽"; static String nameBoy = "郑鑫鑫"; static String name = "幸福"; String love = "一日三餐"; //实例变量:从属于对象,不用初始化,在main方法中使用需要对象.出来,在其他方法时使用不用new int age; char c; //主程序方法 public static void main(String[] args) { //局部变量:必须声明和初始化值 String name = "罗丽"; // int i; // System.out.println(i); System.out.println(name); //输出罗丽而不是幸福 Variable love = new Variable(); System.out.println("love.age = " + love.age + love.c); System.out.println("love.love = " + love.love); love.add(); } //其他方法 public void add(){ System.out.println(nameGirl+nameBoy+name+THING+love); //输出实例变量中的:幸福而不是main方法中的局部变量:罗丽 }
自增、自减运算符
一元运算符
- a++:先赋值再自增,他表现出来是为增加的,但是他的属性已经增加了,如果被触发执行了,那它就会显现出来增加了
- ++a:先自增再赋值
int a = 3; // System.out.println(a++); int b = a++;//先赋值再自增 System.out.println(b);//输出3 //b=a+1=3+1=4 //c=4+1=5 int c = ++a;//先自增再赋值 System.out.println(c);
Math数学计算工具类
double result = Math.pow(4, 2);//幂运算 4的2次方 4^2 System.out.println(result);
l逻辑运算符
- &&:两个小结都为真结果才为真
- ||:两个小结有一个为真结果就为真
- !(a&&b):小结为真则为假,小结为假则为真
- 逻辑运算时的短路(适用于&&与):当第一个小结为假结果直接为假,后边小结将不再判定:
boolean a = true; boolean b = false; System.out.println(a&&b);//两个小结都为真结果才为真 System.out.println(a||b);//两个小结有一个为真结果就为真 System.out.println(!(a&&b));//小结为真则为假,小结为假则为真 //逻辑运算时的短路(适用于&&与):当第一个小结为假结果直接为假,后边小结将不再判定: int i = 3; boolean c = (i>4)&&(i++>4); System.out.println(c); System.out.println(i);//结果还为3,并未进行++,因为(i>4)小结为假
位运算符
根据一位一位的比较运算的,因为符合计算机底层效率,所以计算的速度最快
- &:两个为1才都为1
- |:一个为1就为1
- ^:抑或:相同为1,不相同为0
- ~:取反:完全相反
- << 代表*2
- ->> 代表/2
/* A = 0001 1101 B = 0101 0110 A&B = 0001 0100 两位都为1则为1 A|B = 0101 1111 一位为1就为1 A^B = 1011 0100 两位相同为1 ~B = 1010 1001 1为0、0为1 0000 0000 0 0000 0001 1 逢二进一 0000 0010 2 0000 0011 3 0000 0100 4 0000 0101 5 0000 0110 6 0000 0111 7 0000 1000 8 0001 0000 16 //往左移动一位代表的数字就是该数字的2倍 */ // << 代表*2 // >> 代表/2
三元运算符及小结
- 扩展运算符:+=,-=,*=,/+ 相当于 a = a+b……
- 字符串连接符:"+"(String)类型
int x = 10; int y = 20; System.out.println(x+=y);//结果为30:x=x+y System.out.println(""+x+y);//字符串String在前,结果为拼接 System.out.println(x+y+"");//字符串String在后,结果为先计算再拼接 int score = 50; String result = score>=60?"及格":"不及格";
-
优先级()
包机制
- 一般使用公司域名倒置作为包名:com.kuangshen.www
- 加了包必须在最顶部声明包名:package com.kuangshen.www
- 引入其他包需要import:import java.lang 导入包下所有类的话用*
- 看一遍《阿里巴巴开发手册》
JavaDoc
- @author 作者名
- @version 版本号
- @since 指明jdk版本
- @param 参数名
- @return 返回值情况
- @throws 异常抛出情况
package com.kuangshen.study.base;
/**
* @author :郑鑫鑫
* @version :1.0
* @since 1.8
*
*/
public class Doc {
/**
* @author 郑鑫鑫
* @param name
* @return
* @throws Exception
*/
public String test(String name) throws Exception{
return name;
}
// javadoc -参数 java文件 可以生成javaDoc文档
}
5、Java流程控制
用户交互scanner
基础语法
Scanner input = new Scanner(System.in);
scanner对象的next()方法不能获得有空格的字符串,nextLine()方法可以获得
scanner方法测试
Scanner input = new Scanner(System.in);
if (input.hasNextInt()) {
//使用nextInt()方法接受输入的数字
int num = input.nextInt();
System.out.println("你输入的是整数:" + num);
}
else {System.out.println("请输入整数!");}
if (input.hasNextFloat()) {
System.out.println("你输入的是小数:" + input.nextFloat());
}
else System.out.println("请输入小数");
scanner进阶使用://输入多个数字,求其和与平均数,每个数字用回车来确认,通过非数字来结束输入并输出执行结果
//输入多个数字,求其和与平均数,每个数字用回车来确认,通过非数字来结束输入并输出执行结果
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double sum = 0.0; //计算和
int num = 0; //记录输入的数字
while (scanner.hasNextDouble()){
double input = scanner.nextDouble();
num++;
sum = sum+input;
System.out.println("您输入了第"+num+"个数字,当前数字之和为:"+sum);
}
System.out.println("您通过输入非数字终止了该程序,您一共输入了"+num+"个数字,数字之和为:"+sum+"数字平均值为"+sum+"/"+num+"="+sum/num);
}
顺序结构
- Java的基础结构就是顺序结构
- 顺序结构是最简单的算法结构,是任何一个算法都离不开的一种基础算法结构
选择结构
- if单选择结构
- if双选择结构
- if多选择结构
- switch多选择结构
只要有一个if块为true,程序便执行结束
- 嵌套的if结构
可以在一个if结构里多嵌套几个if来达到细分数据范围提升效率的目的
- Switch多选择结构
Switch在匹配一个具体的值的时候会更方便一点。case穿透:不加break会一直执行下去
String name = "郑鑫鑫";
switch (name){
case "郑鑫鑫":
System.out.println("你输入的没错,开始执行");
case "美女":
System.out.println("郑鑫鑫爱美女,这也没错");
break;
default:
System.out.println("你搞啥子吗");
}
反编译后,字符的本质是数字:hashCode
public SwitchDemo02() {
}
public static void main(String[] args) {
String name = "郑鑫鑫";
byte var3 = -1;
switch(name.hashCode()) {
case 1035173:
if (name.equals("美女")) {
var3 = 1;
}
break;
case 36842993:
if (name.equals("郑鑫鑫")) {
var3 = 0;
}
}
switch(var3) {
case 0:
System.out.println("你输入的没错,开始执行");
case 1:
System.out.println("郑鑫鑫爱美女,这也没错");
break;
default:
System.out.println("你搞啥子吗");
}
循环结构
while(){
}括号内为真会一直执行下去
do{}
while()先执行一次do{}内的代码块,再进行判断,为真跳到do{}
int i = 100;
do {
i++;
System.out.println("满足条件,执行一下"+i);
}while (i>100 && i<150);
//不会进入
while (i>100 && i<150){
System.out.println("满足条件,执行一下while"+i);
}
for循环
for(初始化;布尔值;迭代更新){
}
for循環執行順序:先初始化聲明一種類型,再判斷布爾表達式的值,true執行循環體,FALSE循環終止 ,開始執行循環體後的語句
執行一次循環後才更新循環控制變量(i++或i--)所以i第一次進入循環體為初始值0
100.for()快捷方式,for循环执行的次数是在执行前就确定的
- 计算0到100之间奇数和偶数的和
- 用while或for循环输出1-1000之间能被5整除的数,并且每行输出3个
- 打印99乘法表
int jiSum = 0;
int ouSum = 0;
for (int i = 0; i < 100; i++) {
if (i%2==0){
ouSum+=i;
}else
jiSum+=i;
}
System.out.println("奇数和为:"+jiSum+",偶数和为:"+ouSum);
for (int i = 0; i <= 1000; i++) {
if (i%5==0){
System.out.print(i+"\t");
}
if (i%(5*3)==0) {
System.out.println();
}
}
//1.先打印出99乘法表的第一列
//2.然后用外边的for里的j跑一次,里边的for里的i跑9次得出一个正方形矩阵
//3.我们根据99乘法表得出需要第一次外边的for跑一次,里边的也跑一次,然后一次累加跑成9次所以里边的i<=j就可以了
//4.这样我们就可以得出外边的先是1的时候里边也跑了1,随着外边的不停地加,它的里边也循环的次数变多
//5.j每累加一行就换行
for (int j = 1; j <= 9; j++) {
for (int i = 1; i <= j; i++) {
System.out.print(j + "*" + i + "=" + (j * i)+"\t");
}
System.out.println();
}
增强型for循环
主要是遍历数组和集合的
int[] numbers = {10,20,30,40,50};
for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}
System.out.println("================");
for (int x:numbers)
System.out.print(x+",");
break
用于强行退出循环
continue
用于终止某次循环,当执行到continue时跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定
test打印三角形
//for i走一次,for j走6次 换行;for i走第二次,此时i=1,for j走5次
for (int i=0;i<6;i++){
System.out.println();
for (int j=6;j>i;j--){
System.out.print(" ");
}
for (int j=-1;j<i;j++){//i=0,j<i,j++=1,out 1*;i=1,j=0<i,j++2次!<i,out 2*
System.out.print("*");
}
//顺序结构!!!
for (int j=0;j<i;j++){//布尔值为true先进循环体走完才走i++,才生效,所以第一次循环体里的i=初始值0
System.out.print("*");
}
}
System.out.println(
);
int a = 3;
// System.out.println(a++);
int b = a++;//先赋值再自增
System.out.println(b);//输出3
//b=a+1=3+1=4
//c=4+1=5
int c = ++a;//先自增再赋值
System.out.println(c);//输出5
System.out.println(b);//输出3
}
6、Java方法
什么是方法
System.out.println():类、对象、方法
把一些公共的代码块放在一个方法中,保证main方法的简洁干净,在main中调用就可以了
- 定义:Java的方法类似其他语言的函数,是一段用来完成特定功能的代码片段
- 语法:
方法重载
- 方法名称必须相同
- 参数个数、参数类型、参数顺序必须有一点不同
- JVM会根据实参去匹配形参
- 方法的返回类型可以相同也可以不同
- 仅仅返回类型不同不足以成为方法的重载
//实参 实际传入的参数
int sum = sum(13, 14);
System.out.println(sum);
sum(1,2,3); //加上static可以直接调用
}
//形参 相当于定义了的占位符
public static int sum(int a,int b){
return a*b;
}
public static int sum(int a,int b,int c){
return a*b;
}
命令行传递参数
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
System.out.println("args["+i+"]"+args[i]);
}
}
可变参数
- Java支持传递同类型的可变参数被同一个方法
- 在方法声明中,在指定参数类型后加一个…
- 一个方法中只能声明一个可变参数,并且必须是最后一个参数
函数调用自己的情况叫做递归
-
递归头:什么时候不调用自己
if (n==1){ return 1;
-
递归体:什么情况调用自己(n*f(n-1))
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);
//n*f(n-1) == 5*f(4) n=4
// f(4调用自己) 为 5*f(4) == 5*(n*f(n-1)) == 5*4*f(3)
//5*4*f(3) ==5*4*(n*f(n-1)) == 5*4*3*f(2)
}
计算器
public class TestComputer {
public static int add(int a,int b){
return a+b;
}
public static double add(double a,double b){
return a+b;
}
public static int minus(int a,int b){
return a-b;
}
public static double minus(double a,double b){
return a-b;
}
public static int multiply(int a,int b){
return a*b;
}
public static double multiply(double a,double b){
return a*b;
}
public static int except(int a,int b){
return a/b;
}
public static double except(double a,double b){
return a/b;
}
public static void main(String[] args) {
Scanner num = new Scanner(System.in);
double result = 0.0;
double num1 = 0.0;
double num2 = 0.0;
System.out.print("请输入数字1:");
if (num.hasNextDouble()){
num1 = num.nextDouble();
}else if (num.hasNextInt()){
num1 = num.nextInt();
}else {
System.out.println("请输入数字!!!");
return;
}
System.out.print("请输入运算符:");
String operator = num.next();
System.out.print("请输入数字2:");
if (num.hasNextDouble()){
num2 = num.nextDouble();
}else if (num.hasNextInt()){
num2 = num.nextInt();
}else {
System.out.println("请输入数字!!!");
return;
}
switch (operator){
case "+":
result = add(num1,num2);
break;
case "-":
result = minus(num1,num2);
break;
case "*":
result = multiply(num1,num2);
break;
case "/":
result = except(num1,num2);
break;
default:
System.out.println("请输入正确的运算符!");
return;
}
System.out.println(num1+operator+num2+"="+result);
}
}
7、Java数组
定义
- 数组是相同类型数据的有序集合
- 数组描述的是相同类型的若干数据,按照一定的先后次序排列组合
- 每个数据称作一个数据元素,每个数组元素可以通过一个下标来访问它们
- 数组的声明和创建
public static void main(String[] args) {
int[] nums = new int[5];
int sum = 0;
nums[0] = 1;
nums[1] = 34;
nums[2] = 21;
for (int i = 0; i < nums.length; i++) {
sum+=nums[i];
}
System.out.println(sum);
-
初始化
-
静态初始化:创建+赋值
//静态初始化 int[] nums = {1,23,4,5}; for (int i = 0; i < nums.length; i++) { System.out.println(nums[i]); }
-
动态初始化:包含默认初始化 int为0
//动态初始化 int[] nums2 = new int[4]; for (int i = 0; i < nums2.length; i++) { System.out.println(nums2[i]); }
3.内存:声明在栈中,数据存在堆中,所以需要new,数组对象本身是在堆中的
-
数组的使用
-
普通for循环
int[] nums = {1,2,3,4,5}; for (int i = 0; i < nums.length; i++) { System.out.print(nums[i]+" "); }
-
for-each循环
for (int num : nums) { System.out.print(num); }
-
数组作方法的入参
public static void printArray(int[] nums){ for (int i = 0; i < nums.length; i++) { System.out.print(nums[i]+" "); } }
-
数组作为返回值
public static int[] revers(int[] nums){ int[] result = new int[nums.length]; for (int i = 0,j = result.length-1; i <nums.length; i++,j--) { result[j] = nums[i]; }
二维数组
public static void main(String[] args) {
int[][] array = {{1,2},{3,4},{5,6}};
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
System.out.println(array[i][j]);
}
}
Arrays类
- 冒泡排序

public static void main(String[] args) {
int[] array = {12,32,31,423,4324,12312,243,55};
//12,31,32,423,4324,243,55,12312
//12,31,32,4234,243,55,4324 12312
//12,31,32,243,55,243 4324,12312
int[] sort = sort(array);
System.out.println(Arrays.toString(sort));
}
public static int[] sort(int[] array){
int temp = 0;
for (int i = 0; i < array.length-1; i++) { //第一趟比n-1次 8个数比7次
for (int j = 0; j < array.length-1-i; j++) { //因为第一趟比较后最后一个数已经最大不用参加后边的比较了,所以n-1-i
if (array[j+1]>array[j]){//换容器
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
return array;
}
}
8、面向对象
面向对象的本质:以类的方式组织代码,以对象的组织封装数据
三大特性:
- 封装
- 继承
- 多态
从组成角度是先有对象再有类。对象是具体的事物,类是对对象的抽象
从代码运行角度是先有类后有对象,类是对象的模板
构造器
快捷键:Alt+insert

特点:
- 和类名相同
- 没有返回值也没有void
作用:
- 使用new关键字创建类的对象,本质上是在调用类的构造器
- 无参构造器用来初始化值
注意点:
- 一旦定义了有参构造,无参就必须显示定义
public class Person {
String high;
int age;
int weight;
//无参默认构造器
//一旦定义了有参构造,无参就必须显示定义
public Person() {
}
//有参构造
public Person(String high) {
this.high = high;
}
public Person(String high, int age, int weight) {
this.high = high;
this.age = age;
this.weight = weight;
}
回顾类和方法
-
静态方法和非静态方法:静态方法可以直接通过类名.出来调用,非静态方法需要实例化这个类new来调用
-
static是随着类一起加载的,非static需要实例化才会出现
public static void a(){ b();//无法调用不存在的b方法 } public void b(){ a(); }
-
形参和实参
public static void main(String[] args) { //实参的类型需要与形参一致 int add = new ParameterDemo().add(1, 2); } public int add(int a,int b){ return a+b; }
-
值传递和引用传递
创建对象的内存分析
类:静态的属性,动态的方法
封装
- 该露的露,该藏的藏
- 高内聚,低耦合
- 一般作用于属性 属性私有(private):get/set
- 通过类内部的set/get方法来对该类的私有属性进行赋值/获取
作用:
- 可以避免你去破坏这个系统(可以在set/get方法里加一些逻辑来规避)
- 隐藏代码细节
- 统一接口
- 增加系统可维护性
判断方法是否相同:方法名、参数列表
继承
- 子类是父类的扩展
- 子类拥有父类的所有public属性和方法
- Java只有单继承,没有多继承
- 所有类都会直接或者间接继承Object类
- 私有的无法被继承
super
- this指的是本类中的属性
- super可以调父类中除私有之外的方法
注意点:
public Student() {
super();
System.out.println("Student无参构造被调用");
}
- super 调用父类的构造方法,必须在构造方法的第一行
- super 只能在子类的方法中出现
- super和this不能同时调用构造方法
- this代表本身调用者这个对象
- this和super可以简化代码的编写
方法与变量的执行顺序
public void test(String name){
System.out.println(name);//传入的实参
System.out.println(this.name);//类中的属性
System.out.println(super.name);//父类中的属性
}
public void test1(String name){
print();//本类中的方法
this.print();//本类中的方法
super.print();//父类中的方法
}
构造器执行顺序
-
隐藏代码:先调用父类的无参构造
-
调用父类的构造器,必须在子类构造器的第一行
-
有了有参构造,无参构造必须被显示,否则在子类中无法写父类的无参构造。可以调用父类的有参构造:super("zhangsan")
方法重写
-
重写都是方法的重写,与属性无关
-
重写与静态方法无关,因为静态方法跟随类加载
-
需要有继承关系,子类重写父类的方法
- 方法名必须相同
- 参数列表必须相同
- 修饰符不能为private,继承的权限范围可以扩大,但不能缩小
- 继承的抛出的异常范围可以缩小,不能扩大
子类的方法必须和父类的方法一样,方法体可以不同
当父类的方法不能满足子类时或者用不到全部时,子类可以定制化开发
父类的引用指向子类的对象
注意点
- 输出只跟new后边的子类对象有关
- 静态类只跟左边定义的数据类型有关
多态
注意点:
- 对象能执行的哪些方法是由左边的类型决定的
- 属性没有多态
- 子类没有重写父类的方法时调用的是父类的方法,重写后调用的是子类的方法
Son son = new Son();
Father father = new Son();
son.do1();
father.do1();//子类重写父类方法后父类引用会调用子类对象
son.do2();
// father.do2();父类不能调用本身没有(子类特有)的方法
- 存在条件:
- 继承关系
- 方法需要被重写
- 父类引用指向子类对象
- 无法重写的方法
- static方法
- final方法
- private方法
- instance of 关键字
- 如果匹配就可以进行类型之间的转换
Static关键字
- 静态代码块会随着类先执行并且只执行一次
- 顺序:1.静态代码块 2.匿名代码块 3.构造器
- 一般用于多线程
Abstract抽象类
- 抽象提供一个约束
- 抽象方法只有方法名,没有方法的实现
- 子类继承父类必须重写父类的方法,除非子类也是一个抽象类
- 因为Java类是单继承,所以不常用
- 特点:
-
- 不能new这个抽象类,只能靠子类去重写实现它
- 抽象类中可以有普通方法,但抽象方法必须在抽象类中
-
接口
- 约束和实现分离:面向接口编程
- 接口可以理解为一种特殊的类,里面全部是由*全局常量*和公共的抽象方法所组成。接口是解决*Java无法使用多继承*的一种手段,但是接口在实际中更多的作用是*制定标准*的。或者我们可以直接把接口理解为*100%的抽象类*,既接口中的方法*必须全部*是抽象方法。
声明类的关键字是class,声明接口的关键字是interface
- 使用interface来约束一个类
- 定义一些方法,让不同的人去实现
- 接口中的方法都是 public abstract
- 接口中的属性都是 public static final 并且只能是
- 接口不能被实例化,接口中没有构造方法
- 可以通过implements 关键字实现多个接口,但必须重写接口中的方法
1.语法层面上的区别
1)抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;
2)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
3)接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
4)一个类只能继承一个抽象类,而一个类却可以实现多个接口。
2.设计层面上的区别
1)抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。
抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。
举个简单的例子,飞机和鸟是不同类的事物,但是它们都有一个共性,就是都会飞。
那么在设计的时候,可以将飞机设计为一个类Airplane,将鸟设计为一个类Bird,
但是不能将 飞行 这个特性也设计为类,因此它只是一个行为特性,并不是对一类事物的抽象描述。
此时可以将 飞行 设计为一个接口Fly,包含方法fly( ),然后Airplane和Bird分别根据自己的需要实现Fly这个接口。
然后至于有不同种类的飞机,比如战斗机、民用飞机等直接继承Airplane即可,对于鸟也是类似的,不同种类的鸟直接继承Bird类即可。从这里可以看出,继承是一个 "是不是"的关系,而 接口 实现则是 "有没有"的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有、具备不具备的关系,比如鸟是否能飞(或者是否具备飞行这个特点),能飞行则可以实现这个接口,不能飞行就不实现这个接口。
2)设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。
而接口是一种行为规范,它是一种辐射式设计。什么是模板式设计?
最简单例子,大家都用过ppt里面的模板,如果用模板A设计了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,
如果它们的公共部分需要改动,则只需要改动模板A就可以了,不需要重新对ppt B和ppt C进行改动。
而辐射式设计,比如某个电梯都装了某种报警器,一旦要更新报警器,就必须全部更新。
也就是说对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;
而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。
深入理解Java的接口和抽象类 - Matrix海子 - 博客园 (cnblogs.com)
内部类
- 一个类中只能有一个public修饰的类,内部类可以public
- 内部类可以用来调用外部类私有的方法和属性
- main()方法可以直接写在类中
public class Outer {
private int id = 10;
private void outMethod(){
System.out.println("这是一个外部类的方法");
}
class Inter{
public void getId(){
System.out.println(id);
}
public void getOutMethod(){
System.out.println("内部类调用外部类的方法");
outMethod();
}
}
public static void main(String[] args) {
Outer outer = new Outer();
Inter inter = outer.new Inter();
inter.getId();
inter.getOutMethod();
}
class OuterClass{
}
-
匿名内部类
//调用匿名内部类 //没有名字的初始化类,不用将实例保存在变量中 new Outer().inClass();
9.异常机制
-
异常体系结构
- java把异常当做对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类
- 在Java API中已经定义了许多异常类,这些异常分为错误Error和异常Exception
- 选中代码块可以输入快捷键:ctrl+alt+t 来选择包裹代码块
try{
//监控区域
}catch(想要捕获的异常类型){
}catch(){
//catch类型可以有多个,但必须从小到大
}
finally{
//无论有无异常都会执行的善后工作,一般用于关闭
}
-
抛出异常
public static void main(String[] args) { try { new Demo1().test(1,0); } catch (Exception e) { e.printStackTrace(); } } //方法体处理不了异常就把异常抛出在方法上 public void test(int a,int b)throws ArithmeticException{ if (b==0){ //throw new ArithmeticException(); }
-
总结
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本