Java基础个人学习笔记

重拾Java

Java基础配置

windows常用快捷键

CTRL+C复制

CTRL+V粘贴

CTRL+A全选

CTRL+X剪切

CTRL+Z撤销

WIN+R运行

WIN+E我的电脑

CTRL+SHIFT+ESC任务管理器

ALT+TAB切换


DOS命令

打开CMD方法

1.开始+系统+命令提示符

2.win+R+cmd打开控制台

3.在任意文件夹下,按住shift+鼠标右击

4.在文件地址栏输入cmd 路径

管理员方式运行

常用Dos命令

# 盘符切换
d:
e:
f:
# 查看当前目录下的所有文件
dir
# 换目录 cd (change directory)
cd /d f:  # 切换到f盘
cd ..  # 会到上一级目录
# 清除屏幕
cls
# 退出终端 
exit
# 查看ip
ipconfig
# 打开应用
calc,mspaint,notepad
# ping命令
ping
# 创建文件夹
md
# 新建文件
cd>a.txt
# 删除文件
del a.txt
# 移除文件夹
rd

JDK、JRE、JVM

JDK:Java Devement Kit

JRE:Java Runtime Environment

JVM:Java Virtual Machine

Java开发环境搭建

  • JDK下载与安装(建议安装JavaSE8)
  • 配置虚拟环境
  • Notepad++安装和使用

进入正题

Helloworld

  1. 新建一个文件夹codes用来存放代码
  2. 先建一个java文件,文件名和类名必须相同
    • 文件后缀名是.java
    • Hello.java
    • 第一个java程序
public class Hello{
	public static void main(String[] args){
		System.out.println("Hello,World.");
	}
}

​ 3.在codes中打开终端,编译Java文件,输入:javac Hello.java

​ 4.编译成功后,会生成一个字节码文件,后缀名是.class

​ 5.终端执行java Hello执行文件,输出Hello world

Java程序运行机制

  • 编译型
  • 解释型
  • 程序运行机制(先编译,然后再解释)
    • java源文件(xxx.java)先经过Java编译器生成字节码文件(xxx.class),然后通过类装载器>>>>>字节码校验器>>>>>解释器>>>>>操作系统平台

IEDA安装:

  • IDEA官网:https://www.jetbrains.com

Java基础语法

注释:

  • 单行注释: 以双斜杠“//”标识
  • 多行注释: 包含在“/”和“/”之间
  • 文档注释:包含在“/**”和“*/”之间

标识符和关键字:

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

**标识符:**Java的类名,变量名,方法名都被称为标识符
所有标识符都应该以字母(A-Z,a-z),美元符号 $ 或者下划线_开头
首字符之后可以是字母、美元符号$ 、下划线 _、或者数字的任何字符组合
不能使用关键字作为变量名或者方法名,标识符大小写敏感
可使用中文命名,但一般不建议使用,也不建议使用拼音
合法标识符,例:age,$salary,_value,_1_value
非法标识符,例:123abc,#abc,*salary


数据类型:

基本类型

八种基本数据类型:
  1. 整型:
    • byte
      • 范围:-27~27-1
      • 默认值:0
      • 包装类:Byte
    • short
      • 范围:-215~215-1
      • 默认值:0
      • 包装类:Short
    • int
      • 范围:-231~231-1
      • 默认值:0
      • 包装类:Integer
    • long
      • 范围:-263~263-1
      • 默认值:0
      • 包装类:Long
  2. 浮点型
    • float
      • 单精度,32位
      • 默认值:0.0f
      • 包装类:Float
    • double
      • 双精度,64位
      • 默认值:0.0d
      • Double
    • char:单一的16位Unicode字符。
      • 范围:\u0000\uffff(065355)
      • 包装类:Char
  3. 布尔型:
    • boolean
      • 只有两个取值:true和false
      • 默认值:false
      • 包装类:Boolean
自动类型转换

指不需要编写代码,有系统自动完成的类型转换。由于实际开发中这样的类型转换很多,所有Java语言在设计时,没有为该操作设计语法,而是由JVM自动完成。

转换规则:从存储范围小的类型到存储范围大的类型。

具体规则:byte -> short(char)-> int -> long -> float -> double。

举例说明:byte类型的变量可以自动转换为short类型,

byte b = 11;

short sh = b;

这里在给sh赋值时,JVM首先将变量b的值转换成short类型然后再赋值给sh。

当然,在类型转换的时候可以跳跃,也就是byte可以自动转换为int类型,

注意,在整数之间进行类型转换时数值不会发生变化,但是当将整数类型特别是比较大的整数类型转换成小数类型时,由于存储精度不同,可能会存在数据精度的损失。

public class Demo04 {
    public static void main(String[] args) {
        int i = 128;
        byte b = (byte) i;  // 强制转换
        System.out.println(i);  // 输出128
        System.out.println(b); // 输出-128,byte类型最大127,赋值128会造成内存溢出
        // 强制转换  高--->>>低
        // 自动转换  低--->>>高
        double c = i;
        System.out.println(c);
        /*
        注意点:
        不能把布尔值进行类型转换
        不能把对象类型转换为不相干的类型
        把高容量转换为低容量的时候,强制转换
        转换的时候可能存在内存溢出或者轻度问题
         */
        System.out.println((int) 12.7);  // 输出12
        System.out.println((int) -12.7555f);  // 输出-12

        char c1 = 'a';
        int d = c1 + 1;
        System.out.println(d);
        System.out.println((char) d);

    }
}

public class Demo05 {
    public static void main(String[] args) {
        // 操作数比较大时,注意溢出问题
        int money = 1_000_000_000;  // JDK7新特性
        System.out.println(money);
        int years = 20;
        int total = money * years;
        System.out.println(total);  // 计算的时候溢出

        long total2 = money * (long) years;
        System.out.println(total2);  // int * long = long
    }
}

引用类型

类,接口,shu

拓展:

public class Demo03 {
    public static void main(String[] args) {
        // 整数拓展
        // 进制:二进制0b  十进制  八进制0   十六进制0x   0~9 A~F
        int i = 10;  // 十进制整数
        int i2 = 010;  // 八进制
        int i3 = 0x10;  // 十六进制
        System.out.println(i);
        System.out.println(i2);
        System.out.println(i3);
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>===<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");

        // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        // 浮点数拓展
        // BigDecimal  数学工作类,替代浮点数做运算
        //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        // float       有限  离散  舍入误差   大约  接近但不等于
        // double

        // 最好完全使用浮点数进行比较
        // 最好完全使用浮点数进行比较
        // 最好完全使用浮点数进行比较

        float f = 0.1f;  // 0.1
        double d = 1.0 / 10;  // 0.1
        System.out.println(f == d); // 返回false
        // System.out.println(f);
        // System.out.println(d);
        float d1 = 13526465416534f;
        float d2 = d1 + 1;
        System.out.println(d1 == d2);  // 竟然相等
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>===<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");


        //======================================================================================
        // 字符拓展:所有字符本质就是数字,Unicode编码
        //======================================================================================
        char c1 = 'a';
        char c2 = '中';

        System.out.println(c1);
        System.out.println(c2);
        System.out.println((int) c1);
        System.out.println((int) c2);
        // Unicode编码 0~65536 U0000~UFFFF
        char c3 = '\u0061';  // 查看编码代表的字符
        System.out.println(c3);


        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>===<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");

        // 转义字符
        // \t制表符
        // \n换行
        System.out.println("Hello\tWo\nrld");

        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>===<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
        String sa = new String("hello world");
        String sb = new String("hello world");
        System.out.println(sa == sb);  // 不相等

        String sc = "hello world";
        String sd = "hello world";
        System.out.println(sc == sd);  // 相等

        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>===<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
        // boolean拓展、
        boolean flag = true;
        if(flag){
            System.out.println("true");
        }
        else {
            System.out.println("false");

        }
    }
}

变量

java变量是程序中最基本的存储单元,其包括变量名、变量类型、作用域。java程序中每一个变量都属于特定的数据类型,在使用前必须对其进行声明。
如:int a = 100;
float f =23.3f;
String 是=“hello”;

类变量,实例变量,局部变量
public class Demo07 {
    // 属性:变量

    // 类变量
    static double salary = 123;

    // 实例变量:从属于对象;
    // 布尔值:默认false
    // 除了八大基本变量,默认值都是null;
    String name;
    int age;

    // main方法
    public static void main(String[] args) {
        // 局部变量:必须声明和初始化值,只能在定义其的函数中用
        int i = 10;
        System.out.println(i);  // 局部变量必须初始化

        // 变量类型
        Demo07 demo07 = new Demo07();
        System.out.println(demo07.name);  // 实例变量,不初始化,会输出相应类型的默认值
        System.out.println(demo07.age);  // 实例变量,不初始化,会输出相应类型的默认值


        System.out.println(salary);  // 类变量输入整个类,不需要声明直接使用
    }

    public void add() {

    }
}

常量

特殊的变量,值被设定后,不可改变

public class Demo09 {
    // 修饰符不存在先后顺序
    static final double PI = 3.14;
    final static double PII = 3.14;

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

基本运算符

1.算术运算符: + - / * % ++ --

package operator;

public class Demo04 {
    public static void main(String[] args) {
    	// 二元运算符
        int a = 10;
        int b = 20;
        int c = 25;
        int d = 25;
        System.out.println(a + b);
        System.out.println(a - b);
        System.out.println(a * b);
        System.out.println(a / b);  // 输出0
        System.out.println(a / (double) b);  //输出0.5
        // ===================================================
        // ++自增 --自减
        int a = 3;
        int b = a++;  // 执行完代码后,先给b赋值,再自增
        System.out.println(a);

        int c = ++a;  // 执行完代码后,先自增,再赋值
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);

        // 幂运算,使用Math类操作一些运算
        double aa = Math.pow(3, 2);
        System.out.println(aa);
    }
}

2.赋值运算符: =

public class Demo07 {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;

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

        // 字符串连接 +
        System.out.println("" + a + b); // 1020
        System.out.println(a + b + ""); // 30

    }
}

3.关系运算符: < > <= >= == != instanceof

4.逻辑运算符: &&(与) ||(或) !(非) &(与) | (或)

package operator;

// 逻辑运算符
public class Demo05 {
    public 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 k = 2;
        //++k==2  先进行i自增,k=3,再进行k==2,返回false
        //k++==3  不会执行
        System.out.println((++k == 2) && (k++ == 3));  // false
        System.out.println(k);  // 3  可以简单来想,因为只有左侧的boolean表达式执行计算,那么k只有1次++,就会只加1。
    }
}

5.三目运算符:

public class Demo08 {
    public static void main(String[] args) {
        // 三元运算符
        int a;
        a = 10 > 20 ? 10 : 20;
        System.out.println(a);
    }
}

6.位运算: &(与) |(或) ^(异或)>>(右移) <<(左移)(了解)

package operator;

public class Demo06 {
    public static void main(String[] args) {
        /*
        A = 0011 1100
        B = 0000 1111
        C = 0000 1100  & 与
        C = 0011 1111  | 或
        C = 0011 0001  ^ 异或
        ~B = 1111 0010  取反

        2*8 = 16  2*2*2*2
        <<左移一位扩大两倍  >>右移一位减小两倍
        */
        System.out.println(2<<3);
        System.out.println(64>>3);
    }
}

包机制:

包通俗来说就是一个文件夹,为了防止文件名重复冲突而提出的一个概念

为了更好的组织类,java提供了包机制,用于区分类名的命名空间。
包语句的语法格式为:
package pkg1[.pkg2[.pkg3…]];
1
一般利用公司域名倒置作为包名;
为了能够使用某一包的成员,我们需要在java程序中明确导入改包。使用“import”语句可完成此功能
import package1[.package2…].(classname|*);


JavaDoc

标签 描述 在 JDK/SDK 中引入
@author 名称文本,仅限类和接口 1.0
{@code} 显示文本,而不会将文本解释为 HTML 标记或嵌套的 javadoc 标签 1.5
{@docRoot} 指明当前文档根目录的路径 1.3
@deprecated 弃用文本,指名一个过期的类或成员,表明该类或方法不建议使用 1.0
@exception 可能抛出异常的说明,一般用于方法注释 1.0
{@inheritDoc} 从直接父类继承的注释 1.4
{@link} 插入一个到另一个主题的链接 1.2
{@linkplain} 插入一个到另一个主题的链接,但是该链接显示纯文本字体 1.4
{@literal} 显示文本,而不会将文本解释为 HTML 标记或嵌套的 javadoc 标签 1.5
@param 说明一个参数,仅限方法和构造器 1.0
@return 说明返回值类型,仅限方法 1.0
@see 指定一个到另一个主题的链接 1.0
@serial 说明一个序列化属性 1.2
@serialData 说明通过 writeObject() 和 writeExternal() 方法写的数据 1.2
@serialField 说明一个 ObjectStreamField 组件 1.2
@since 说明从哪个版本起开始有了这个函数 1.1
@throws 和 @exception 标签一样. 1.2
{@value} 显示常量的值,该常量必须是 static 属性。 1.4
@version 指定版本,仅限类和接口 1.0

参考:https://blog.csdn.net/manongajie/article/details/121494903


Java流程控制

Scanner对象

  • 实现程序和人的交互

  • Scanner s = new Scanner(System.in);

  • 通过Scanner类的next和nextLine方法获取输入的字符串,读取时使用hasNext和haxNextLine判断时候还有输入的数据

  • next()

    • 一定要读取到有效字符后才可以结束输入
    • 对输入有效字符之前遇到空白,next()方法会自动去除掉
    • 只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符
    • next()不能得到带有空格的字符串
  • nextLine()

    • 以Enter为结束符,也就是说nextLine()方法返回的是输入空格之前的所有字符
    • 可以获得空白

顺序结构

java的基本结构,程序一条一条执行

选择结构

if语句

1.单选择结构
if(布尔表达式){
    //如果布尔表达式为true将执行语句
}
2.双选择结构
if(布尔表达式){
    //如果布尔表达式为true将执行语句
}else{
    //如果布尔表达式为false将执行语句
}
3.多选择结构
if(布尔表达式1){
    //如果布尔表达式1为true将执行语句    
}else if(布尔表达式2){
    //如果布尔表达式2为true将执行语句
}else if(布尔表达式3){
    //如果布尔表达式3为true将执行语句
}else if(布尔表达式4){
    //如果布尔表达式4为true将执行语句
}else{
    //如果以上布尔表达式都不为true将执行语句
}

switch语句

多选择结构
switch(expression){
    case value :
        //语句
        break;//可选
    case value :
        //语句
        break;//可选
    case value :
        //语句
        break;//可选
        //可以有任意数量的case语句
    default ://可选
        //语句
}

循环结构

while循环

public static void main(String[] args) {
    // 输出1~100
    int i = 0;
    while (i <= 99) {
        i++;
        System.out.println(i);
    }
}

只要布尔表达式为true,循环体会一直执行下去。

do…while循环

对于while语句而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次。
Do…while循环和while循环相似,不同的是,do…while循环至少会执行一次。

public static void main(String[] args) {
    int i = 0;
    int sum = 0;
    do {
        i++;
        sum+=i;
    }while (i<100);
    System.out.println(sum);
}

注意:布尔表达式在循环体的后面,所以语句块在检测布尔表达式之前已经执行了。如果布尔表达式的值为true,则语句块一直执行,直到布尔表达式的值为false。


For循环

虽然所有循环结构都可以用while或者do…while表示,但Java提供了另一种语言——for循环,使一些循环结构变得更加简单。
For循环执行的次数是在执行前就确定的。语法格式如下:

public static void main(String[] args) {
    for (int a = 1; a <= 100; a++) {
        System.out.println(a);
    }
}

关于for循环有以下几点说明:

  • 最先执行初始化步骤。可以声明并初始化一个或多个循环控制变量,也可以是空语句。
  • 然后检查布尔表达式的值。如果为true,循环体被执行。如果为false,循环终止,开始执行循环体 后面的语句。
  • 执行一次循环后,更新循环控制变量。
  • 再次检测布尔表达式。循环执行上面的过程。

案例1

打印九九乘法表

public static void main(String[] args) {
    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循环

public static void main(String[] args) {
    // 定义一个数组
    int[] numbers = {10, 20, 30, 40, 50};
    for (int i = 0; i < numbers.length; i++) {
        System.out.println(numbers[i]);
    }
    // 遍历数组的元素,将numbers里的每个元素取出来赋值给x然后输出
    for (int x : numbers) {
        System.out.println(x);
    }
}

break,continue

  • break
public static void main(String[] args) {
    int i = 0;
    while (i < 100) {
        i++;
        System.out.println(i);
        if (i == 30) {
            break;
        }
    }
    System.out.println("break只是跳出当前循环层,并没有终止程序");
}
  • continue
public static void main(String[] args) {
    for (int i = 0; i <= 100; i++) {
       if ((i & 1) == 1) {
           continue;
        }
        System.out.println("得到的一定是偶数:" + i);
    }
}
  • 标签
public static void main(String[] args) {
    // 打印101-150之间的所有质数
    int count = 0;
    outer:
    for (int i = 101; i < 150; i++) {
        for (int j = 2; j < i / 2; j++) {
            if (i % j == 0) {
                continue outer;
            }
        }
        System.out.print(i + "\t");
    }
}

打印三角形:

public static void main(String[] args) {
    // 打印三角形
    for (int i = 1; i <= 5; i++) {
        for (int j = 5; j >= i; j--) {
            System.out.print(" ");
        }
        for (int j = 1; j <= i; j++){
            System.out.print("*");
        }
        for (int j = 1; j < i; j++){
            System.out.print("*");
        }
            System.out.println();
    }
}

Java方法

概述

  • Java方法是语句的集合,他们在一起执行一个功能
    • 方法是解决一类问题的步骤的有序集合
    • 方法包含于类和对象中
    • 方法在程序中被创建,在其他地方被引用
  • 设计方法的原则:功能块,实现某个功能的语句块的集合,保持方法的原子性:一个方法只完成一个功能。

方法定义

方法必须先创建才可以使用,该过程称为方法定义

格式:public static void 方法名(){

方法体

}

public static void main(String[] args) {
    System.out.println(max(10, 50));
}

// 比大小
public static int max(int a, int b) {
    return a > b ? a : b;

}

方法的重载

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

  • 规则
    • 方法名称必须相同
    • 参数列表必须不同
    • 返回类型可以相同也可以不相同
    • 仅仅返回类型不同不足以成为方法的重载
  • 理论:
    • 方法名称相同时,编译器会根据调用方法的参数个数、类型等逐个匹配,已选择对应的方法,如果匹配失败,编译器会报错
// 方法的重载
public static void main(String[] args) {
    System.out.println(max(10, 50));
    System.out.println(max(10.1,23.11));
}

// 比大小
public static int max(int a, int b) {
    return a > b ? a : b;
}

// 名称必须相同,参数必须不同,返回类型随意
public static double max(double a, double b) {
    return a > b ? a : b;
}

可变参数(不定项参数)

  • 在方法的声明中,在指定参数类型后加一个省略号(…)
  • 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在他之前声明。
public static void main(String[] args) {
    Demo05 demo05 = new Demo05();
    demo05.test(1, 2, 3, 4, 5, 6);
}

public void test(int x, int... i) {
    System.out.println(i[0]);  // 本质是数组
    System.out.println(i[4]);
    System.out.println(i[5]);
}

递归

自己调用自己

// 阶乘
public static void main(String[] args) {
    System.out.println(factorial(5));
}

public static int factorial(int n) {
    if (n == 1) {
        return 1;
    }else {
        return n * factorial(n - 1);
    }
}

Java数组

定义:

数组是相同类型元素的集合。创建数组的时候,Java就会再内存中分配一段连续的空间来存放数组的内容。每一个数组内容都有自己的编号,这个编号从0开始的,也就是数组的下标从0开始。通过数组的下标来访问数组的内容。

声明数组

// 变量类型 变量名 = 变量值
// 数组类型
public static void main(String[] args) {
    int[] numbers1;  // 首选方法
    // int numbers2[];  // 不推荐
    // 使用new操作符创建数组
    int[] numbers3 = new int[10];  // 可以存放10个int类型的数字
    numbers3[0] = 1;
    numbers3[1] = 2;
    numbers3[2] = 3;
    numbers3[3] = 4;
    numbers3[4] = 5;
    numbers3[5] = 6;
    numbers3[6] = 7;
    numbers3[7] = 8;
    numbers3[8] = 9;
    numbers3[9] = 10;
    for(int x:numbers3){
        System.out.print(x + "\t");
    }
}

三种初始化状态

  • 静态初始化
    • int[] a = {1,2,3};
    • Man[] mans = {new Man(1,1),new Man(2,2)};
  • 静态初始化
    • int[] a = new int[2];
    • a[0] = 1;
    • a[1] = 2;
  • 默认初始化
    • 数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。
public static void main(String[] args) {
    // 静态初始化
    int[] a = {1, 2, 3, 4};
    Man[] mans = {new Man(), new Man()};  // 引用类型

    // 动态初始化:包含默认初始化
    int[] b = new int[10];  // 默认值为0,需要手动赋值
    System.out.println(b[5]);
}

小结

  • 长度确定,一旦被创建,大小不可改变
  • 元素必须是相同类型,不允许出现混合类型
  • 元素可以是任何数据类型,包括基本类型和引用类型
  • 数组变量属于引用类型,数组也可以堪称对象,数组的每个元素相当于刚对象的成员变量
  • 数组本身就是对象,Java对象在堆中,因此数组无论保存原始类型还是其他对象类型,数组对象本身在堆中
  • 数组也是对象,数组元素相当于对象的成员变量

数组的使用

public static void main(String[] args) {
    int[] arrays = {1, 2, 3, 4, 5};
    System.out.println(maxArray(arrays));
    System.out.println(sumArray(arrays));
    printArray(reverse(arrays));
}

public static int maxArray(int[] arrays) {
    // 查找最大元素
    int max = arrays[0];
    for (int x : arrays) {
        max = x > max ? x : max;
    }
    return max;
}

public static int[] reverse(int[] arrays) {
    int[] result = new int[arrays.length];
    for (int i = 0; i < arrays.length; i++) {
        result[arrays.length - 1 - i] = arrays[i];

    }
    return result;
}

public static void printArray(int[] arrays) {
    // 打印全部数组元素
    for (int x : arrays) {
        System.out.print(x + "\t");
    }
}

public static int sumArray(int[] arrays) {
    // 计算所有元素的和
    int sum = 0;
    for (int x : arrays) {
        sum += x;
    }
    return sum;
}

多维数组

public static void main(String[] args) {
    int[][] array1 = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
    int[][] array2 = new int[4][4];  // 4x4的数组
    for (int[] x : array1) {
        for (int y : x) {
            System.out.print(y + "\t");
        }
        System.out.println();
    }
    System.out.println("========================================================================");
    for (int i = 0; i < array1.length; i++) {
        for (int j = 0; j < array1[0].length; j++) {
            System.out.print(array1[i][j] + "\t");
        }
        System.out.println();
    }
}

Arrays类

数组的工具类java.util.Arrays

常用方法
  • equals:比较一维数组

    • //equals:比较一维数组
       System.out.print("arr1==arr2 is ");
       System.out.println(Arrays.equals(arr1,arr2));//比较的是内容
      
  • sort:对数组升序排序

  • fill:填充数组

  • toString:打印出数组每个元素

    • System.out.println("用println打印arr1结果为:"+arr1);//打印的是地址
      // toString:打印出数组每个元素
      String a1 = Arrays.toString(arr1);
      System.out.println("用toString打印sort排序结果:"+a1);
      
  • copyOf:对指定数组进行复制,使副本有指定长度

    • //copyOf:对指定数组进行复制,使副本有指定长度
      int [] a2 = Arrays.copyOf(arr1,arr1.length-1);//长度少一位
      System.out.println("经copyOf的新数组:"+Arrays.toString(a2));
      
  • binarySearch:一定要先排序,二分查找下标

    • //binarySearch:一定要先排序,二分查找下标
      int index = Arrays.binarySearch(a2,4);
      System.out.println("4的下标为"+index);
      
  • asList:数组转为列表

    • (1)该方法适用于对象型数据的数组(String、Integer…)

      (2)该方法不建议使用于基本数据类型的数组(byte,short,int,long,float,double,boolean)

      (3)该方法将数组与List列表链接起来:当更新其一个时,另一个自动更新

      (4)不支持add()、remove()、clear()等方法

    • //asList;转为列表
      String[] s={"aa","bb","cc"};
      List<String> stringList =Arrays.asList(s);
      System.out.print("经asList转为列表:");
      for(String str:stringList){
         System.out.print(str+"");
            }
      
  • 示例

    package array;
    
    import java.util.List;
    import java.util.Arrays;
    
    public class ArrayDemo05 {
        public static void main(String[] args) {
            int[] arr1 = {4, 9, 1, 2, 10};
            int[] arr2 = {4, 9, 1, 2, 10};
            //equals:比较一维数组
            System.out.print("arr1==arr2 is ");
            System.out.println(Arrays.equals(arr1, arr2));//比较的是内容
    
            //sort:对数组升序排序
            Arrays.sort(arr1);
    
            System.out.println("用println打印arr1结果为:" + arr1);//打印的是地址
            //toString:打印出数组每个元素
            String a1 = Arrays.toString(arr1);
            System.out.println("用toString打印sort排序结果:" + a1);
    
            //copyOf:对指定数组进行复制,使副本有指定长度
            int[] a2 = Arrays.copyOf(arr1, arr1.length - 1);//长度少一位
            System.out.println("经copyOf的新数组:" + Arrays.toString(a2));
    
            //binarySearch:一定要先排序,二分查找下标
            int index = Arrays.binarySearch(a2, 4);
            System.out.println("4的下标为" + index);
    
            //asList;转为列表
            String[] s = {"aa", "bb", "cc"};
            List<String> stringList = Arrays.asList(s);
            System.out.print("经asList转为列表:");
            for (String str : stringList) {
                System.out.print(str + "");
            }
        }
    }
    

冒泡排序

package array;

import java.util.Arrays;

public class ArrayDemo06 {
    public static void main(String[] args) {
        int[] arr1 = {4, 9, 1, 2, 10};
        System.out.println(Arrays.toString(sort(arr1)));
    }

    // 冒泡排序
    // 比较相邻元素,如果第一个数比第二个数大,交换位置
    // 每一次比较,就会产生出一个最大或者最小的数字
    // 依次循环知道结束
    public static int[] sort(int[] array) {
        // 临时变量
        int temp;
        // 外层循环,判断要走多少次
        for (int i = 0; i < array.length; i++) {
            boolean flag = false;  // 通过flag标志位减少没有意义的比较
            // 内层循环,如果第一个数比第二个数大,交换位置
            for (int j = 0; j < array.length - 1; j++) {
                if (array[j + 1] < array[j]) {
                    temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                    flag = true;
                }
            }
            if (!flag){
                break;
            }
        }
        return array;
    }
}

稀疏数组

  • 当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
  • 稀疏数组的处理方式是:记录数组一共有几行几列,有多少个不同值;把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模
  • 如下图:左边是原始数组,右边是稀疏数组
package array;

public class ArrayDemo07 {
    public static void main(String[] args) {
        // 创建一个二维数组 11*11 0:无棋子 1:黑棋 2:白棋
        int[][] array1 = new int[11][11];
        array1[1][2] = 1;
        array1[2][3] = 2;

        // 输出原始数组
        for (int[] ints : array1) {
            for (int anInt : ints) {
                System.out.print(anInt + "\t");
            }
            System.out.println();
        }
        System.out.println("================================================================");
        // 转换为稀疏数组
        // 获取有效值的个数
        int sum = 0;
        for (int i = 0; i < array1.length; i++) {
            for (int j = 0; j < array1[i].length; j++) {
                if (array1[i][j] != 0) {
                    sum += 1;
                }
            }

        }
        System.out.println("有效值个数:" + sum);
        System.out.println("================================================================");
        // 创建一个稀疏数组的数组
        int[][] array2 = new int[sum + 1][3];
        array2[0][0] = array1.length;
        array2[0][1] = array1[0].length;
        array2[0][2] = sum;
        // 遍历二维数组,将非0的值,存入稀疏数组中
        int count = 0;
        for (int i = 0; i < array1.length; i++) {
            for (int j = 0; j < array1[i].length; j++) {
                if (array1[i][j] != 0) {
                    count++;
                    array2[count][0] = i;
                    array2[count][1] = j;
                    array2[count][2] = array1[i][j];
                }
            }

        }
        // 打印稀疏数组
        for (int[] ints : array2) {
            for (int anInt : ints) {
                System.out.print(anInt + "\t");
            }
            System.out.println();
        }
        System.out.println("================================================================");
        // 还原稀疏数组
        // 读取稀疏数组
        int[][] array3 = new int[array2[0][0]][array2[0][1]];
        // 还原值
        for (int i = 1; i < array2.length; i++) {
            array3[array2[i][0]][array2[i][1]] = array2[i][2];
        }
        // 打印还原数组
        for (int[] ints : array3) {
            for (int anInt : ints) {
                System.out.print(anInt + "\t");
            }
            System.out.println();
        }

    }
}

面向对象(OPP)

概述:

面向对象编程的本质:以类的方式组织代码,以对象的组织(封装)数据。

面向对象就是把构成问题的事物分解成一个个对象,建立对象不是为了实现一个步骤,而是为了描述某个事物在解决问题中的行为。

类是面向对象中的一个很重要的概念,因为类是很多个具有相同属性和行为特征的对象所抽象出来的,对象是类的一个实例。

类具有三个特性:封装、继承和多态

  • 封装:核心思想就是“隐藏细节”、“数据安全”,将对象不需要让外界访问的成员变量和方法私有化,只提供符合开发者意愿的公有方法来访问这些数据和逻辑,保证了数据的安全和程序的稳定。
  • 继承:子类可以继承父类的属性和方法,并对其进行拓展。
  • 多态:同一种类型的对象执行同一个方法时可以表现出不同的行为特征。通过继承的上下转型、接口的回调以及方法的重写和重载可以实现多态。

创建与初始化对象

Aplication.java

package OOP.Demo02;

public class Application {
    public static void main(String[] args) {
        // 类:抽象的,需要实例化
        // 类实例化后会返回一个自己的对象
        // ss对象就是Student类的具体实例
        Student ss1 = new Student();
        Student ss2 = new Student();
        ss1.name = "骡子";
        ss2.name = "吸螺";
        ss2.age = 83;
        ss1.study();
        ss2.study();  // 没有赋值,默认为null
        System.out.println(ss2.name + "今年" + ss2.age + "岁了");
    }
}

Student.java

package OOP.Demo02;

// 学生类
public class Student {
    // 属性:字段
    String name;
    int age;

    // 方法
    public void study() {
        System.out.println(this.name + "学生在学习。");
    }
}

构造器

[修饰符,比如public] 类名 (参数列表,可以没有参数){

//不能有return,不会返回值也不要写void

}

Application.java

package OOP.Demo02;

public class Application {
    public static void main(String[] args) {
        // 实例化了一个对象
        Person person = new Person();
        System.out.println(person.name);
        Person person1 = new Person("骡子");
        System.out.println(person1.name);

    }
}

Person.java

package OOP.Demo02;

public class Person {
    // 一个类即使什么也不写,也会存在构造方法
    // 显示的定义构造器
    String name;
    int age;

    public Person() {
        // 构造器:名字必须和类名相同,没有返回值
        // 使用new关键字,本质是调用构造器进行初始化,必须要有构造器
        // 初始化值

    }

    // ALT + INSERT 生成构造器
    public Person(String name) {
        // 重载构造器
        // 有参构造器, 一旦定义了有参构造,无参就必须显示定义
        this.name = name;
    }

    public Person(String name, int age) {
        // 重载构造器
        // 有参构造器, 一旦定义了有参构造,无参就必须显示定义
        this.name = name;
        this.age = age;
    }

}

封装

Application

package OOP.Demo04;

public class Application {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.setName("骡子");  // 使用set方法设置私有属性
        System.out.println(s1.getName());  // 使用get方法获得私有属性
        s1.setAge(999);  // 不合法
        System.out.println(s1.getAge());
    }
}

Student.java

package OOP.Demo04;

public class Student {
    // 名字 private:私有
    private String name;
    // 学号
    private int id;
    // 性别
    private char sex;

    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age > 120 || age < 0) {
            this.age = 3;

        } else {
            this.age = age;
        }
    }

    // 学习()

    public String getName() {
        return name;
    }

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

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public char getSex() {
        return sex;
    }

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


    // 睡觉()
}

继承

继承是面向对象程序设计语言的基石之一。
只需在新的类中产生现有类的对象 的方式叫做组合,按照现有类的类型来创建新类的方式为继承

1、在java中使用 extends关键字实现类的继承机制

class Parent {
}
class Child extends Parent {
}

类Parent为父类,Child为子类。

2、通过继承子类会自动拥有基类(父类)所有的成员变量和方法。

3、一个子类只能有一个基类,一个基类可以有多个子类。就像一个儿子只能有一个父亲,但一个父亲可能会有多个儿子。故java只支持单继承,不支持多继承。,终极基类(父类)为java标准类Obiect。

super

  • super注意点:
    • super调用父类的构造方法,必须在构造方法的第一个
    • super必须只能出现在子类的方法或者构造方法中
    • super和this不能通知调用构造方法
  • this:本身调用者这个对象,没继承也可以使用
  • super:代表父类对象的应用,只有在继承条件下才能使用
  • this():本类的构造
  • super():父类的构造
Application.java
package OOP.Demo05;

// java中,所有类默认继承Object类
public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.say();  // 子类继承父类所有方法
        System.out.println(student.money);  // 子类继承父类公有方法
        // Ctrl+h
        System.out.println(student.getClass());  // 获取类名
        student.test("阿威罗");
    }
}
Person.java
package OOP.Demo05;

public class Person {

    public Person(String class_name){
        System.out.println("person有参构造器");
    }
    public Person(){
        System.out.println("Person无参构造器");
    }
    protected String name = "粑粑螺";
    public int money = 100_000_000;
    private int age = 50;

    public void say() {
        System.out.println("说了一句话");
    }
    public void print(){
        System.out.println("siu~~~");
    }
    // private 无法被继承

}

Student.java
package OOP.Demo05;

// 子类继承父类,就拥有了父类全部方法
public class Student extends Person {
    private String name = "骡子";

    public Student() {
        // 隐藏代码super();
        super("Person");  // 必须放在第一行,不写也行
        System.out.println("Student无参构造器");
    }

    public void test(String name) {
        System.out.println(name);
        System.out.println(this.name);
        System.out.println(super.name);
        print();  // 默认调用自己的print
        this.print();  // 指定print
        super.print();  // 调用父类的print

    }

    public void print() {
        System.out.println("Std siu~~~");
    }
}

方法的重写

  • 前提:需要有继承关系
  • 子类重写父类的方法
  • 方法名必须相同
  • 参数列表必须相同
  • 修饰符:范围可以扩大,但不能缩小 public>protected>Default>private
  • 抛出的异常:范围可以被缩小,但不能扩大 ClassNotFoundException —>Exception(大)

子类的方法和父类必须一致,方法体不同

  • 为什么要重写
    • 子类不一定需要或满足父类的方法
Application.java
package OOP.Demo05;

// java中,所有类默认继承Object类
public class Application {
    public static void main(String[] args) {

        // 静态方法:方法的调用只和左边,定义的数据类型有关
        // 非静态方法:重写
        A a = new A();
        a.test();  // A
        // 父类的引用指向子类
        B b = new A();  // 子类重写了父类的方法
        b.test();  // B
    }
}
A.java
package OOP.Demo05;

// 重写都是方法的重写,和属性无关
public class A extends B{
    // 重写
    @Override
    public void test() {
        System.out.println("A=>test()");
    }
}
b.java
package OOP.Demo05;

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

多态

实现多态的条件:

1.继承:必须要有子类继承父类的继承关系。
2.重写:子类需要对父类中的一些方法进行重写,然后调用方法时就会调用子类重写的方法而不是原本父类的方法。
3.向上转型:在多态中需要将父类引用指向子类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。

父类引用指向子类对象

此引用只可以调用父类的方法,如果父类的方法被子类重写,那么就会调用在子类中重写的方法

注意事项

  • 多态是方法的多态,属性没有多态
  • 父类和子类有联系 类型转换异常ClassCastException
  • static方法,属于类,不属于实例
  • final 常量
  • private方法:私有方法不能重写

instanceof

x instanceof y

Object object = new Student();
System.out.println(object instanceof Student);  // true
System.out.println(object instanceof Person);  // true
System.out.println(object instanceof Object);  // true
System.out.println(object instanceof Teacher);  // false
System.out.println(object instanceof String);  // false
System.out.println("===============================");

Person person = new Student();
System.out.println(person instanceof Student);  // true
System.out.println(person instanceof Person);  // true
System.out.println(person instanceof Object);  // true
System.out.println(person instanceof Teacher);  // false
System.out.println("===============================");

Student student = new Student();
System.out.println(student instanceof Student);  // true
System.out.println(student instanceof Person);  // true
System.out.println(student instanceof Object);  // true

转型

  • 子类引用指向子类的对象
  • 把子类转换为父类,向上转型
  • 把父类转换为子类,向下转型,强制转换
  • 方便方法调用,减少重复代码,简洁代码

Application.java

package OOP.Demo06;

public class Application {
    public static void main(String[] args) {
        // 一个对象的实际类型是确定的
        // new Person();
        // new Student();
        // 可以指向的引用类型不确定

        // Student能调用的方法都是自己的或者继承父类的
        Student s1 = new Student();
        // Person 父类型:可以指向子类,但不能调用子类的方法
        Person s2 = new Student();  // 父类的引用指向子类
        Object s3 = new Student();  // 父类的引用指向子类

        // 对象能执行哪些方法,只要看对象左边的类型,和右边关系不大
        s2.run();  // 子类重写了父类的方法
        s1.run();
        // s2.eat();
	
        // 类型之间的转换: 父类-->子类
        Person person = new Student();
        ((Student) person).eat();  // 将person转换为Student类型

        // 子类 --> 父类  会丢失方法,只能调用父类的方法或者在子类中被重写的方法
        Student student = new Student();
        student.eat();
        Person person1 = student;
        ((Student) person1).eat();
        person1.run(); // 只能调用父类的方法或者在子类中被重写的方法
        	
    }
}

Person.java

package OOP.Demo06;

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

Student.java

package OOP.Demo06;

public class Student extends Person {
    @Override
    public void run() {
        System.out.println("siu~~~");
    }
    public void eat(){
        System.out.println("siu吃");
    }
}

Teacher.java

package OOP.Demo06;

public class Teacher extends Person {
    public void go() {
        System.out.println("gogogosiu");
    }
}

Static

Person.java

package OOP.Demo07;

public class Person {
    {
        // 匿名代码块
        System.out.println("匿名代码块");
    }

    public Person() {
        System.out.println("构造方法");
    }

    static {
        // 静态代码块,跟类加载一起被执行,静待代码块只执行一次
        System.out.println("静态代码块");
    }
}

Student.java

package OOP.Demo07;

// Static和类加载一起被加载
public class Student {
    private static int age;  // 静态变量
    private double score;  // 非静态

    public static void go() {
        System.out.println("Siu~~~go");
    }

    public void run() {
        go();
        System.out.println("Siu~~~ren");
    }

    public static void main(String[] args) {
        Student s1 = new Student();
        System.out.println(Student.age);  // 静态变量可以直接类名.属性名
        // System.out.println(Student.score);
        s1.run();
        Student.go();
        System.out.println("=============");
        Person p1 = new Person();
        System.out.println("=============");
        Person p2 = new Person();  // 静待代码块只执行一次
    }
}

Test.java

package OOP.Demo07;
// 静态导入包
import static java.lang.Math.*;

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

抽象类

特点

  • 不能new这个抽象类,只能靠子类去实现他:约束!
  • 抽象类里可以写普通方法
  • 抽象方法必须写在抽象类中

注意事项

  • 抽象类是有构造器的,由于抽象类不能被实例化,所以不能直接new从而调用其构造方法。想使用抽象类的构造方法可以让子类实现抽象类的抽象方法,当new子类的一对象时,子类的构造方法里会自动执行super() 从而执行了抽象类的构造方法。
  • 子类继承抽象类必须实现其抽象方法,除了子类是抽象类这种情况。

A.java

package OOP.Demo08;

public class A extends Action{
    @Override
    public void do_something() {
        // 重写抽象父类的方法
    }
}

Action.java

package OOP.Demo08;

// abstract抽象类
public abstract class Action {
    // 只有方法名,没有方法体
    public abstract void do_something();  // 其普通子类必须实现每个抽象方法,抽象子类则不然
}

接口

  • 接口声明了一组能力,但它自己并没有实现这个能力,它只是一个约束。
  • 接口的本质是契约
  • 不能被实例化
  • 可以实现多继承
  • 必须重写接口的方法

UserServiceImpl.java

package OOP.Demo09;

// 实现了接口的类,必须重写接口方法,可以继承多个接口
public class UserServiceImpl implements UserService, TimeService{
    // 属性默认常量 public static final
    int age = 99;
    @Override
    public void add(String name) {

    }

    @Override
    public void delete(String name) {

    }

    @Override
    public void update(String name) {

    }

    @Override
    public void query(String name) {

    }

    @Override
    public void timer() {

    }
}

TimeService.java

package OOP.Demo09;

public interface TimeService {
    void timer();
}

UserService.java

package OOP.Demo09;

public interface UserService {
    // 接口中的所有定义都是抽象的默认都是public abstract
    public abstract void add(String name);

    void delete(String name);

    void update(String name);

    void query(String name);
    // 接口都需要实现类

}

内部类

Application.java

package OOP.Demo10;

public class Application {
    public static void main(String[] args) {
        Outer outer = new Outer();
        // 通过外部类实例化内部类
        Outer.Inner inner = outer.new Inner();
        outer.out();
        inner.in();
        inner.getId();
        inner.getOut();
    }
}

Test.java

package OOP.Demo10;

import OOP.Demo09.UserService;

public class Test {
    public static void main(String[] args) {
        Apple apple = new Apple();
        // 没有名字初始化类
        new Apple().eat();  // 不用把实例保存在变量中
        UserService userService = new UserService() {
            @Override
            public void add(String name) {

            }

            @Override
            public void delete(String name) {

            }

            @Override
            public void update(String name) {

            }

            @Override
            public void query(String name) {

            }
        };

    }

}

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

Outer.java

package OOP.Demo10;

public class Outer {

    public void method(){
        class Inner{
            // 局部内部类
            public void in(){
                System.out.println("局部内部SIU");
            }
        }
    }
    private int id = 101;

    public void out() {
        System.out.println("outer~Siu~~~");
    }

    class Inner {
        public void in() {
            System.out.println("inner~Siu~~~");
        }

        public void getId() {
            // 获得外部的私有属性
            System.out.println(id);
        }

        public void getOut() {
            out();
        }
    }
}

// 一个Java类中可以有多个class类,但只能有一个public class,不能写public
class A {
    public static void main(String[] args) {

    }
}

异常机制

Java中的异常(Exception)又称为例外,是一个在程序执行期间发生的事件,它中断正在执行程序的正常指令流。为了能够及时有效地处理程序中的运行错误,必须使用异常类。

异常产生的原因

  • 编写程序代码中的错误产生的异常,比如数组越界、空指针异常等,这种异常叫做未检查的异常,一般需要在类中处理这些异常

  • Java内部错误发生的异常,Java虚拟机产生异常

  • 通过throw(抛出异常)语句手动生成的异常,这种异常叫做检查的异常,一般是用来给方法调用者一些必要的信息

异常体系结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gzudmCPe-1666010832497)(E:\个人笔记\java\imgs\image-20221009162636344.png)]

  1. Throwable:是异常体系的顶层类,其派生出两个重要的子类, Error 和 Exception而 Error 和 Exception 两子类分别表示错误和异常。区别就是不检查异常(Unchecked Exception)和检查异常(Checked Exception)。

  2. Exception 类用于用户程序可能出现的异常情况,它也是用来创建自定义异常类型类的类。

  3. Error 定义了在通常环境下不希望被程序捕获的异常。Error 类型的异常用于 Java 运行时由系统显示与运行时系统本身有关的错误。堆栈溢出是这种错误的一例。

异常处理机制

Test.java

package exception;

public class Test {
    public static void main(String[] args) {
        int a = 1;
        int b = 0;

        try {
            new Test().test(a, b);
        } catch (ArithmeticException e) {
            e.printStackTrace();
        }


    }

    public void a() {
        b();
    }

    public void b() {
        a();
    }

    // 假设这个方法无法处理此异常,方法是抛出异常
    public void test(int a, int b) throws ArithmeticException {
        if (b == 0) {
            throw new ArithmeticException();  // 主动抛出异常,一般用在方法中
        }

    }
}

/*
try {  // 监控区域
            if (b == 0) {
                throw new ArithmeticException();  // 主动抛出异常
            }
            System.out.println(a / b);
        } catch (ArithmeticException e) {  // 捕获异常
            System.out.println("程序出现异常:" + e);
        } finally {  // 善后
            System.out.println("finally");
        }
        // fianlly 可不不写

        try {
            new Test().a();
        } catch (Error e) {  // 多个异常从小到大
            System.out.println("异常类型:" + e);

        } catch (Exception e) {
            System.out.println("Exception:" + e);

        } catch (Throwable e) {
            System.out.println("Throwable:" + e);
        }
 */

Test2.java

package exception;

public class Test2 {
    public static void main(String[] args) {
        int a = 1;
        int b = 0;
        // Ctrl+ALT+T
        try {
            System.out.println(a / b);
        } catch (Exception e) {

            e.printStackTrace();  // 打印错误的栈信息
        } finally {
        }
    }
}

自定义异常

自定义异常类的使用步骤如下:

  1. 自定义异常类继承Exception类

    /**
    
     * 自定义异常类
       */
       public class MyException extends Exception {
       //异常信息
       private String message;
    
       //构造函数
       public MyException(String message){
           super(message);
           this.message = message;
       }
    
       //获取异常信息,由于构造函数调用了super(message),不用重写此方法
       //public String getMessage(){
       //    return message;
       //}
       }
    
  2. 在要抛出异常的函数使用throws关键字

    /**
     * 在需要抛出异常的地方使用异常类
     */
    public class UseMyException {
        private String name;
        private String password;
    
        public UseMyException(String name,String password){
            this.name = name;
            this.password = password;
        }
    
        public void throwException(String password) throws MyException{
            if (!this.password.equals(password)){
                throw new MyException("密码不正确!");
            }
        }
    }
    
  3. 测试,使用try-catch处理异常

    /**
     * 测试异常
     */
    public class TestException {
    
        @org.junit.Test
        public void test(){
            UseMyException ex = new UseMyException("admin","123");
            try{
                ex.throwException("1234");
            }catch (MyException me){
                System.out.println("MyException:"+me.getMessage());
            }
        }
    }
    

内存分析

  • (1)栈(Stack):存放的都是方法中的局部变量,方法的运行一定要在栈中运行。
    局部变量:方法的参数,或者是方法{}内部的变量。
    作用域:一旦超出作用域,立刻从栈内存当中消失。
  • (2)堆(Heap):凡是new出来的东西,都在堆当中。堆内存里面的东西都有一个地址值:16进制。堆内存里面的数据,都有默认值。规则:
    如果是整数: 默认是0
    如果是浮点数: 默认是0.0
    如果是字符: 默认是’\u0000’
    如果是布尔: 默认是false
    如果是引用类型: 默认是null
  • (3)方法区(Method Area):存储.class相关信息,包含方法的信息。
  • (4)本地方法栈(Native Method Stack):与操作系统相关。
  • (5)寄存器(pc Register):与CPU有关。
  • 原文参考:https://blog.csdn.net/qq_36294338/article/details/109717306
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hai是啥都不会

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值