学习JavaSE这一篇就够了

JavaSE 基础

第一章 计算机基础知识

1.1 计算机发展趋势和二进制以及语言发展史

1.1.1 计算机的发展趋势
  • 微型化
  • 巨型化
  • 智能化
1.1.2 二进制
  • 计算机只能识别 0 和 1,所以在进行存储时,都是通过二进制来进行存储的
  • 0 和 1 简单,所以可以代表电的低频和高频
  • 也可以进行一些逻辑运算
  • 还可以通过逻辑门电路来实现一些运算
1.1.3 语言发展史
  • 机器语言

  • 汇编语言

  • 高级语言

1.2 Java 发展史 、Java体系、Java 平台

1.2.1 Java 发展史
  • Java 源自于 sun 公司,创始人是 高司令,起源于 green 项目
  • 2009 年 sun 被 Oracle 收购
  • 没被收购之前,每两年更新一次
  • 收购之后,每半年更新一次
  • 目前稳定版:jdk8、jdk11
1.2.2 Java 体系

请添加图片描述

1.2.3 Java 平台
  • JavaSE(基础版)

  • JavaEE(面向企业级应用桌面程序开发)

  • JavaME(嵌入式开发)

1.3 Java 如何实现跨平台的

请添加图片描述

1.4 开发软件

  • 高级文本编辑器:Notepad++
  • 开发软件:IDEA

1.5 常用的 DOS 命令

  • 命令的几种形式?

    • 内部命令(操作系统内置)
    • 外部命令(通过安装第三方软件,需要进行一些配置)
    • 批处理文件(bat)
  • 命令的使用方式

    • help 命令
    • 命令 [属性] [路劲]
  • 常用的命令

    • cd (进入指定的目录结构)
    • cd …(返回上一级)
    • cd /(返回根目录)
    • dir(查看当前目录,有哪些文件和目录)

1.6 JDK 的安装与配置

  • JDK 官网
  • 软件安装,双击运行,一直下一步

请添加图片描述

1.7 书写第一个HelloWorld

1.7.1 代码示例
public class HelloWorld {
    public static void main(String[] args) {
        System.out.prinlnt("HelloWorld");
    }
}
1.7.2 DOS 命令编译执行 Java 源文件
  • javac(用来将 Java 源文件,编译成 .class 文件)
  • java(执行 Java.class 文件)
    • java 命令后面,不能直接跟路劲,需要加上 -classpath 属性
    • java -classpath 路劲 类名
  • 点击:gif 图片演示
1.7.3 命令的执行步骤
  • 命令在执行时,先会在当前所属目录去查找

  • 当前所属目录没有,就会去环境变量里面去找

  • 环境变量

    • 用户变量(只对当前用户生效)

    • 系统变量(对整个系统生效)

    • 先去用户变量中查找,没有找到,再去系统变量中找,找到就执行

    • 没有找到,如下图

请添加图片描述

1.8 Java 环境变量配置

  • 为什么需要配置环境变量?

    • 如果不进行配置,DOS 执行对应的命令时,需要去对应命令所属的目录里面去执行
    • 而且命令所执行的文件(目标),跟命令不在同一位置
    • 配置完,环境变量后,就可以在任意目录使用命令
  • 示例
    点击:环境变量 git 演示

  • 为什么需要配置 JAVA_HOME?

    • JAVA_HOME 这个名字本身,是可以随便起的
    • 但是由于大不部分人,都用 JAVA_HOME 这个名字
    • 所以就导致有些软件需要用到 Java 环境,但是在查找 Java 环境时,是通过 JAVA_HOME 去查找的,如果没有找到就会报错!!
    • 不容易错删,方便我们切换版本
  • 为什么需要配置 path?

    • path 里面包含了 windows 环境变量 中 可执行文件的绝对路径
    • 由于 JDK 我们可能要安装多个版本,但是 JDK 版本的目录不同,所以遵循 “变化导入,不变保留”
    • JAVA_HOME 里面定义 JDK 的目录
    • path 里面引入 JAVA_HOME ,并拼接对应的 bin 目录
  • 为什么不配置 CLASSPATH

    • 在 JDK 1.5 之前,Java 命令无法完成 .class 文件的执行,需要通过 CLASSPATH 配置一些内容,来完成类的执行
    • JDK 1.5 之后,就不需要配置 CLASSPATH 了

第二章 Java 的基础知识

2.1 Java 程序的常见错误

  • 类名必须和文件名保持一致

  • 严格区分大小写

  • 单词拼错

  • { } 缺失

  • 标点符号是中文的

2.2 HelloWorld 程序解析

  • public class HelloWorld {
         
        public static void main(String[] args) {
         
            System.out.println("HelloWorld");
        }
    }
    
  • public (公共的)

    • 在一个 Java 源文件中,public 只能有一个
  • class (类)

    • 在一个 Java 源文件中,class 可以有多个,在编译的过程中,会将这些 class 分别编译成 class 文件
    • class 类想要执行必须包含 main 方法
  • HelloWorld (类名)

    • 类名和文件名必须保持一致
    • 大小写分明
  • public static void main(String[] agrs) {} (main 方法,程序的执行入口)

    • static 静态的
    • void 空的
    • main (方法名)
    • [](数组)
  • System.out.println()(打印输入内容)

    • System(系统)

    • out(输出)

    • println(打印换行)

    • print(打印)

    • () 需要打印的内容

2.3 注释

  • 用于描述代码,方便别人进行查看和维护

  • /**
    	文档注释
    	用于声明类的信息,和帮助文档
    */
    public class Test {
        /*
        	多行注释
        	main 方法
            程序执行的入口
        */
        public static void main(String[] args) {
            // 单行注释
            System.out.println("注释");
        }
    }
    
  • 单行注释和多行注释,只在编码环境中生效

  • 文档注释的生命周期在,编译环境

2.4 标识符

  • 不能以数字开头
  • 首字母可以用 26个英文字母 或 下划线 或者 $ 开头,后面可以跟字母、下划线、$ 和 数字
  • 标识符不可以是关键字
  • 严格区分字母大小写
  • 驼峰命令法
    • 大驼峰
      • 单个单词,首字母大写
      • 多个单词,每个单词的首字母大写,其余字母小写
      • 类、接口、注解
    • 小驼峰
      • 单个单词,全部小写
      • 多个单词,从第二个单词开始,每个单词的首字母大写,其余字母小写
      • 变量、方法

2.5 关键字

  • 在 Java 中,已经规定了其用法的单词,这些单词不能作为标识符,关键字又称为保留字。

  • 常用的关键字

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sihkcd9Y-1638851240009)(…/…/image/JavaSE/01_计算机基本知识/关键字.jpg)]

2.6 字符集合

  • 字符集合是指一个国家的所以文字和字符的集合
  • 不同国家的字符各有差异
  • 计算机是老外发明的,底层是用 ASCII 表来字符进行存储的
    • 输入一个字符,就会去对应的字符表中去找当前字符对应的数字
    • 请添加图片描述
  • 当一个国家的文字出现,另一个国家的字符表中,那么就会乱码
  • 解决方案
    • 修改文件编码的格式或修改解码文件的格式
    • 文件编码和解码格式必须做到统一
    • javac -encoding utf-8 文件名

2.5 变量

  • 内存地址的引用,在生命周期期间可以重复引用

  • 变量的语法

    • 数据类型 变量名 = 值;
  • 变量的三要素

    • 数据类型、变量名、作用域(生命周期 作用范围)
  • 图解

请添加图片描述

  • public class Test {
        public static void main(String[] args) {
            /*
            *   变量的声明方式?
            *       先声明后初始化
            *       声明并初始化	
            *  在 Java 中,变量必须先初始化,才能被引用,否则就会报错
            */
            int num;
            num = 20;
            System.out.println(num);
            num = 30;
            System.out.println(num);
    
            int num2 = 30;
        }
    }
    

2.6 常量

  • 通过 final 进行修饰,一旦赋值就不可

第三章 数据类型与运算符以及流程控制语句

3.1 数据类型分类

  • 基本数据类型
    • 整数类型
      • byte (字节型)、short(短整型)、int(整形)、long(长整型)
    • 浮点型
      • float(单精度浮点型)、double(双精度浮点型)
    • 字符型
      • char
    • 布尔型
      • boolean
  • 引用数据

3.2 数据类型介绍

数据类型 范围
byte 1个字节 -27~27-1 [-128~127]
short 2个字节 -215~215-1 [-32768~32767]
int 4个字节 -231~231-1 [-2147483648~2147483647] 约21亿
long 8 个字节 -263~263 -1
float 4 个字节 精确到小数点为7
double 8 个字节 是 float 的两倍
char 2 字节 0~65535
boolean 1 个字节
3.2.1 整数类型
  • public class Test {
         
        public static void main(String[] args) {
         
           //byte
            byte num = 127;
            //错误:从 int 转 byte 会造成精度丢失,不兼容
            //num = 128;
            System.out.println(num);
    
            //short
            short num2 = 32767;
            //错误:从 int 转 short 会造成精度丢失,不兼容
            //num2 = 32768;
    
            //int
            int num3 = 2147483647;
            //错误:过大的整数
            //num3 = 2147483648;
            System.out.println(num3);
            
            //long
            long num4 = 2147483647;
            num4 = 2147483648L;
            System.out.println(num4);
        }
    }
    
  • 注意:

    • 在 Java 中所有整数类型的字面值是 int 类型, 在给数据类型赋值时,不超过对应类型赋值范围,那么这个值,就是对应的数据类型
    • 一旦超过,这个值就会真正的变成 int 类型,int 赋值 比他小的数据类型,会导致精度丢失,不兼容
    • 在值的后面加上 L 表示 long 类型
  • 赋值方式

    public class Test {
         
        public static void main(String[] args) {
         
            // 二进制 0b 开头
            int num = 0b101010;
            // 八进制 0 开头
            int num2 = 01234567;
            // 十进制 正常写
            int num3 = 1025;
            // 十六进制 0x 开头
            int num4 = 0x125EA;
        }
    }
    
3.2.2 浮点数
  • public class Test {
         
        public static void main(String[] args) {
         
            //有效小数点 7 位
            float num = 2.12547858f;
            System.out.println(num);
    
            //double 能够精确到小数点 15 位
            double num2 = 2.1111111111111189 ;
            System.out.println(num2);
    
            //计算机是用二进制来存储数据,所以有些小数不能精确的表示
            double num3 = 0.1;
            double num4 = 0.1;
            System.out.println(num3 == num4); // true
            num4 = 1/10;
            System.out.println(num3 == num4);  // false
        }
    }
    
  • 注意

    • 在 Java 中所有浮点型默认值是 double 类型,所以在给 float 赋值时,后面需要加上 f 或 F
    • double 类型的值,可以在后面加上 d 或 D
    • 由于浮点数能够精确表示的小数有限,有些小数不能精确的表示,所以浮点数不适合做四则运算
    • 想要做科学运算,可以使用 BigDecimal
  • 赋值方式

    public class Test {
         
        public static void main(String[] args) {
         
            // 小数的整数如果是0,那么0可以省略
            double num = .5;
            // 科学计数法 314.0  0.314
            double num2 = 3.14E2;
            double num3 = 3.14E-1;
        }
    }
    
3.2.3 字符型
  • 由于 Java 是采用 Unicode 进行编码的,Unicode 每位字符的存储是2个字节,所以它范围是 0~65535 之间也可以使用 Unicode 的形式进行赋值

  • char 类型为什么可以赋值数字,首先计算机是通过 ASCII 表进行存储的,同时 Unicode 兼容 ASCII 表

  • public class Test {
         
        public static void main(String[] args) {
         
            //char 通过 '' 来进行赋值
            char str = 'A';
            System.out.println(str);
            System.out.println(str + 10);
            //通过数字来赋值
            str = 97;
            System.out.println(str);
            System.out.println(str + 10);
    
            //通过 Unicode 进行赋值
            str = '\u0000';
            System.out.println(str);
        }
    }
    
  • 注意事项

    • ‘’ 表示的是字符,"" 表示的是字符串,它们两个不一样
3.2.4 布尔型
  • boolean 是布尔类型,它的值是 true 和 false,通过 true 和 false 又代表 1 和 0

  • public class Test {
         
        public static void main(String[] args) {
         
            boolean flag = true;
            flag = 20>25;
            System.out.println(flag);
        }
    }
    
  • 注意事项

    在 <<Java 虚拟机规范>> 一书中写道,虽然定义了 boolean,但是却没有指定其范围,所以 boolean 类型在被编译时,

    默认是当做 int 类型来处理的,但如果是 数组 类型,那么就会被当做 byte[] 来处理

3.3 数据类型转换

3.3.1 隐式类型转换

请添加图片描述

请添加图片描述

  • 实线箭头表示转换不会丢失精度,虚线箭头表示转换会损失精度
  • 隐式转换就是由小向大转换,不会造成精度丢失
3.3.2 强制类型转换
  • 由大向小转换,会造成精度丢失

  • public class Test {
         
        public static void main(String[] args) {
         
            // int 转 byte
            int num = 20;
            byte num2 = (byte)num;
            // long 转 int
            long num3 = 20L;
            int num4 = (int)num3;
    
            //四则运算
            int num5 = (int)(20*5+25L/3.0d);
        }
    }
    
  • 在进行四则运算中,最终结果以数据类型最大的那个为主,但是可能这个值的数据类型和变量的数据类型,不匹配需要强转

3.4 转义字符

  • 将特殊含义的字符,转换成普通字符串

  • \t \n \r \

  • 一般就是用 \t 和 \n 其他的看看就好,不重要!!

  • public class Test {
         
        public static void main(String[] args) {
         
            /*
            *   \n    换行,将光标移动到下一行首行
            *   \r    将光标,移动到当前行的首行
            *          如 \r 前后都有内容,那么后面的内容就会替换前面的所有内容
            *
            *   \t    空格 8 位,如果 \t 前面有字符串,那么就会根据字符串的个数和8对减,从而得出
            *         打印多少个空格,如果前面的字符串个数是8个,那么 \t 就会打印 8 个空格
            *         如果 \t 前面没有内容,会打印 8 个空格, \t 前面的内容不仅可以是字符串
            * \       将有特殊含义的字符,转换成普通的字符串
            */
            System.out.println("sdssdf" + "\n" + "sdfsd");
            System.out.println("11111" + "\r" + "a");
            System.out.println('a'+'b'+"\t" + "1");
            System.out.println("\t" + "1");
            System.out.println("\\");
            System.out.println("\"");
        }
    }
    

3.5 运算符

3.5.1 什么是表达式?

请添加图片描述

3.5.2 算数运算符
  • + - * / % ++ --

  • public class Test {
         
        public static void main(String[] args) {
         
            //+ - * / % ++ --
            int num = 10;
            System.out.println(num + 10);
            System.out.println(num - 10);
            System.out.println(num * 20);
            System.out.println(num / 5);
            // % 取模 除于这个数,并取余
            System.out.println(num % 5);
    
            //在四则运算中,有多个数据类型,进行运算,最终结果的数据类型,以最大的那个为主
            //注意:因为操作数是两两进行运算的,在没有碰到那个最大的数据类型之前,操作数的类型都是默认类型
            double num2 = 20/8;
            System.out.println(num2);
            num2 = 20d/25*9L;
            num2 = ((double) 30)/65*23.6f+25L;
            System.out.println(num2);
    
            /*
             * + 既可以做加法运算也可以做字符串拼接符号
             * 当表达式中,既有加法运算也有字符串拼接,此时则不在进行运算
             * 除非表达式中,还有其他运算,那么就会先进行除加法之外的运算符运算,在进行拼接
             */
            //1HelloWorld026
            System.out.println(1+"HellWorld"+1/2+2+2*3);
    
            // ++ 自增
            // ++ 在操作数后面的,被称为后自增,后自9.ui增是先运算在+1
            int num3 = 10;
            int num4 = num3++;
            System.out.println(num4);
            System.out.println(num3);
            // ++ 在操作数前面被称为,前自增,前自增先+1后运算
            num4 = ++num3;
            System.out.println(num4);
            System.out.println(num3);
            num3++;
            System.out.println(num3);
    
            // -- 自减
            // -- 在操作数后面,被称为后自减,后自减是先运算在-1
            int num5 = 20;
            int num6 = num5--;
            System.out.println(num6);
            System.out.println(num5);
            // -- 在操作数前面,被称为前自减,前自减是先-1在运算
            num6 = --num5;
            System.out.println(num6);
            System.out.println(num5);
            //当 ++ 和 -- 写成独立的一条语句时,那么最终结果一定是自增或自减
            --num5;
            System.out.println(num5);
        }
    }
    
  • 注意事项:

    • ++ 和 – 要注意在操作数前面和后面的区别
    • ++ 和 – ,可以单独写成一条语句,那最终的结果一定是自增或自减
    • + 既可以做加法运算,也可以做字符串拼接
2.5.3 赋值运算符
  • 在 Java 中 = 是赋值运算符,== 是等于运算符
3.5.4 关系运算符
  • > >= < <= == != instanceof

  • public class Test {
         
        public static void main(String[] args) {
         
            // > >= < <= == != instanceof
            //关系运算符最终的运算结果一定是 布尔值
            System.out.println(20 > 5);
            System.out.println(20 < 5);
            System.out.println(20 >= 20);
            System.out.println(5 <= 30);
            System.out.println(1 == 2);
            System.out.println(2 != 1);
        }
    }
    
  • 注意

    • != 和 == 即可以判断基本数据类型也可以判断引用类型
    • instanceof 只能判断引用数据类型
    • > >= < <= 只能判断基本数据类型
    • = 和 == 的区别
3.5.5 扩展运算符
  • += -= /= *=

  • public class Test {
         
        public static void main(String[] args) {
         
            // += -= *= /=
            int num = 20;
            //num = num + (10 + 2)
            num += 10 + 2;
            // num = num - 20;
            num -= 20;
            // num = num * (20/5)
            num *= 20/5;
            // num = num / (2*3)
            num /= 2*3;
            
            // 可以进行隐式转换
            num *= 20L+3;
            num += 23.6f+1;
            System.out.println(num);
        }
    }
    
  • 扩展运算符的优缺点

    • 扩展运算符可以进行隐式转换
    • 优点
      • 提高开发效率和编译效率
    • 缺点
      • 可读性变差了
3.5.6 逻辑运算符
  • & && | || ! ^

  • public class Test {
         
        public static void main(String[] args) {
         
            // && || ! ^
            // && 两个表达式的条件为true,结果为true,否则为 false
            System.out.println((20 < 15) && (30 > 32));
            // || 两个表达式其中一个为 true,则结果为 true,否则为 false
            System.out.println((10 > 20) || (25 < 10));
            // ! 取反
            System.out.println(!(10 == 2));
            //相同为 false,不同为 true
            System.out.println((10 > 2) ^ (10 < 2));
        }
    }
    
  • 注意事项

    • & 和 && 的区别
      • & 左边表达式为 false,右边表达式也计算
      • && 左边表达式为 false,右边则不在计算
    • | 和 || 的区别
      • | 左边表达式为 true,右边还要计算
      • || 左边表达式为 true,右边则不在计算
3.5.7 三目运算符
  • 表达式1?表达式2:表达式3

  • 如果表达式1的值为 true,那么就执行表达式2,如果为 false,则执行表达式3

  • public class Test {
         
        public static void main(String[] args) {
         
            //三元运算符
            int num = 20;
            int num2 = 30;
            System.out.println(num>num2?"num大于num2":"num小于num2");
            //计算三个数的最大值
            int num3 = 15;
            int max = num>num2?(num2>num3?num2:num3):(num2<num3?num3:num2);
            System.out.println(max);
        }
    }
    
3.5.8 位运算
  • & | ~ ^ << >> >>>

  • public class Test {
         
        public static void main(String[] args) {
         
            // & | ~ >> >> >>>
            //相同为true,不同为 false
            //101
            // 10
            //000
            System.out.println(5&2);
    
            //只要有一个为1,那么就是 1
            //1010
            // 101
            //1111
            System.out.println(10|5);
    
            //相同为 false,不同为 true
            //1010
            // 101
            //1111
            System.out.println(10^5);
    
            //取反
            //00101
            //11010 补码,负数在计算机中是用补码来进行存储和计算的,所以这个数取反之后,就变成了补码
            //11001 尾数减 1 变成 补码
            //10110 符号位不变,其余数字按位取反,变成原码
            System.out.println(~5);
    
            //左移2位 -5*2^2,左移不管是正数还是负数后面都是补0
            System.out.println(-5<<2);
            //左移2位 5*2^2
            System.out.println(5<<2);
    
            //右移2位,10/2^2
            System.out.println(10>>10);
            //右移2位,-10/2^2,右移正数前面补0,负数前面补1
            System.out.println(-10>>2);
    
            // >>> 如果是正数按照 >> 来计算
            System.out.println(-10>>>8);
        }
    }
    
  • 扩展

    • & 可以判断一个数基偶性

      • 基数尾数一定是1

      • System.out.println(5&1); // 1
        System.out.println(4&1); // 0
        
    • ^ 可以交换两个数的位置

      • public class Test {
                 
            public static void main(String[] args) {
                 
                int a = 5;
                int b = 2;
                //n^n^m = m
                a = a ^ b; // 101^10 = 111  7
                b = a ^ b; // 111 ^ 10 = 101  5
                a = b ^ a; // 111 ^ 101 = 10  2
                System.out.println(a);
                System.out.println(b);
            }
        }
        
3.5.9 运算符的优先级

请添加图片描述

  • 单目》双目》多目
  • 想要控制运算符的顺序,请使用小括号!!!
  • 不要试图使用运算符的优先级来控制运算顺序!!!

3.6 流程控制语句

3.6.1 选择控制语句
3.6.1.1 if 语句

表达式中的结果只能是布尔类型

if 单分支

语法

// 如果表达式为true,则执行逻辑代码
if (表达式) {
   
    逻辑代码
}

示例

import java.util.Scanner;
public class Test {
   
    public static void main(String[] args) {
   
        //键盘录入
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入数字");
        //获取输入的内容
        int num = sc.nextInt();
        //if 判断数字是否大于等于 50
        if (num >= 50) {
   
            System.out.println("当前数字大于等于50");
        }
    }
}

多分支

语法

// 如果表达式的值为 true,则执行逻辑代码1,否则就执行逻辑代码2
if (表达式) {
   
    逻辑代码1
}else {
   
    逻辑代码2
}

示例

import java.util.Scanner;
public class Test {
   
    public static void main(String[] args) {
   
        //键盘录入
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入数字");
        //获取输入的内容
        int num = sc.nextInt();
        //if 判断数字是否大于等于 50
        if (num >= 50) {
   
            System.out.println("当前数字大于等于50");
        }else {
   
            System.out.println("当前数字小于50");
        }
    }
}

多分支

语法

// 程序会依次判断表达式中的值是否对等,如果对等就执行相应的逻辑代码,如果最终都没选中,则执行 else
// 如表达式1不等,就判断表达式2,表达式2不等,就判断表达式3,表达式3相等则执行对应的逻辑代码,其他都不执行
if (表达式1) {
   
    逻辑代码1
}else if (表达式2) {
   
    逻辑代码2
}else if (表达式3) {
   
    逻辑代码3
}else {
   
    逻辑代码4
}

示例

import java.util.Scanner;
public class Test {
   
    public static void main(String[] args) {
   
        //键盘录入
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入数字");
        //获取输入的内容
        int num = sc.nextInt();

        // 输入学生的成绩判断,属于哪个水平
        if (num > 10 && num <= 20) {
   
            System.out.println("男女混合双打");
        }else if (num > 20 && num <= 30) {
   
            System.out.println("男子单打");
        }else if (num > 30 && num <= 40) {
   
            System.out.println("女子单打");
        }else if (num > 40 && num <= 50) {
   
            System.out.println("骚年继续努力");
        }else if (num > 50 && num <= 60) {
   
            System.out.println("不及格");
        }else if (num > 60 && num <= 70) {
   
            System.out.println("勉强及格");
        }else if (num > 70 && num <= 80) {
   
            System.out.println("一般");
        }else if (num > 80 &&num <= 90) {
   
            System.out.println("优秀");
        }else if (num > 90 && num <= 100) {
   
            System.out.println("顶尖");
        }else {
   
            System.out.println("退学!!!!!");
        }
    }
}

注意事项

  1. if 多分支最好不要超过3个,不含 else
  2. 尽量简化 if 分支,多变双,双边单
  3. 逻辑代码最好不要写在 if 里面,建议写在外面,推荐报错写在 if 里面,根据情况来定
3.6.1.2 switch 语句

语法

// 判断表达式的值,是否与 case 的值相等,如果相等则执行对应 case 的语句里面的代码,如果最终都未选中则执行 default
switch(表达式) {
   
    case1:
        执行代码1
    case2:
        执行代码2
    case3:
        执行代码3
    .....
    default:        
}

示例

import java.util.Scanner;
public class Test {
   
    public static void main(String[] args) {
   
        //键盘录入
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入名称");
        //获取输入的内容
        String name = sc.nextLine();

        //根据名称,返回对应的专业信息
        switch (name) {
   
            case "小丁":
                System.out.println("计算机");
                //break 跳出 switch 语句
                break;
            case "小明":
                System.out.println("电子商务");
                break;
            case "小红":
                System.out.println("直播带货");
                break;
            case "小兰":
                System.out.println("土木工程");
                break;
            default:
                System.out.println("未选择专业");
                break;
        }
    }
}
import java.util.Scanner;
public class Test {
   
    public static void main(String[] args) {
   
        //键盘录入
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入月份");
        int num = sc.nextInt();

        //根据月份判断季节
        switch(num) {
   
            case 11:
            case 12:
            case 1:
                System.out.println("冬季");
                break;
            case 2:
            case 3:
            case 4:
                System.out.println("春季");
                break;
            case 5:
            case 6:
            case 7:
                System.out.println("夏季");
                break;
            case 8:
            case 9:
            case 10:
                System.out.println("秋季");
                break;
            default:
                System.out.println("请输入正确的季节!!!");
                break;
        }
    }
}

注意事项

  1. 从 jdk1.5 开始之后,支持枚举,1.7 支持 String
  2. 除了long、boolean、float、double,其他基本数据类型均可使用
  3. 注意 switch 穿透,当前对应的 case 对等时,则执行 case 里面对应的语句,此时 case 里面没写 break 语句的话,那么程序就会一次往下执行,无视 case 条件,知道碰到 break 为止,如果最终没有碰到 break ,那么程序就会执行到末尾,包括 default
  4. 在 switch 中 default 顺序乱放(避免 switch 穿透的情况下),不会影响程序的执行
  5. int、byte、short、int 和 char 一样,char 三种赋值方式,均可在 switch 中执行,对应的整数类型也行
  6. if 常用与区间对比,switch 用于固定值判断
3.6.2 循环控制语句
3.6.2.1 while 循环

语法

while(表达式) {
   
    执行内容
}

示例

public class Test {
   
    public static void main(String[] args) {
   
        //计算1~100的累加和
        //定义初始化变量
        int num = 1;
        //存储累加和
        int sum = 0;
        //如果 num <= 100,则循环就会一直执行,知道 num 值 大于 100,则跳出循环
        while (num<=100) {
   
            //sum = sum + num;
            sum += num;
            //每循环一次,num的值就 +1,表达式条件的变更
            //如果表达式的值,一直不变,那么就会变成死循环
            num++;
        }
        //输出 sum 的值
        System.out.println(sum);
    }
}

执行顺序

  1. 先判断
  2. 如果条件为 true ,则执行一次,在判断在执行
  3. 直到条件为 false,则循环结束,执行后续代码

注意事项

  1. 先判断在执行
  2. 循环的三要素(初始化变量、表达式、表达式条件变更)
  3. while 适合,知道判断条件,却不知道执行次数场景使用
3.6.2.2 do while 循环

语法

//do while 循环是先执行在判断
do {
   
    执行代码
}while(表达式);

示例

public class Test {
   
    public static void main(String[] args) {
   
        //定义一个随机数,如果随机数的值是<=99,那么就一直执行,直到这个随机数>99
        //存储随机数
        int num = 0;
        //先执行,后判断
        do {
   
            //获取随机数
            num = (int)(Math.random()*100+1);
            //打印随机数
            System.out.println(num);
        }while (num <= 99);//条件判断
    }
}

执行顺序

  1. 先执行,判断条件是否为 true,为 true 则继续执行,在判断
  2. 当条件为 false,则终止循环,执行后续代码

注意事项

  1. do while 和 while 的区别是:do while 是先执行在判断,while 是先判断在执行
  2. do while 适合,根据一个值,来判断是否继续要执行,比如说 腾讯QQ登录
3.6.2.3 for 循环

语法

for (;;) {
   
    执行内容
}

示例

public class Test {
   
    public static void main(String[] args) {
   
        //循环打印10遍 HelloWorld
        //i 初始值,i<10 是判断条件,i++ 条件变更
        //我们发现 for 其实跟 while 很像,for 只是将三要素定义到了括号了
        for (int i = 0;i<10;i++) {
   
            System.out.println("HelloWorld");
        }

        /*
         *  死循环
         *      1、有初始值,判断条件,无条件变更
         *      2、有初始值,无判断条件
         *      3、三个都不写
         */
//        for (int j = 0;j<10;) {
   
//            System.out.println("有初始值,判断条件,无条件变更");
//        }
//        for (int k = 0;;k++) {
   
//            System.out.println("有初始值,无判断条件");
//        }
//        for (;;) {
   
//            System.out.println("三个都不写");
//        }
    }
}
public class Test {
   
    public static void main(String[] args) {
   
        //计算 1~100 的累计和,当累加和等于3000时,累加到那个数字
        //存储累加和
        int sum = 0;
        for (int i = 1;i<=100;i++) {
   
            sum += i;
            if (sum == 3000) {
   
                System.out.println(i);
            }
        }
    }
}
public class Test {
   
    public static void main(String[] args) {
   
        //计算1~100之间所有的偶数,5个一行打印输出
        //存储累加和
        int sum = 0;
        //记录次数
        int count = 0;
        for (int i = 1;i<=100;i++) {
   
            //判断 i 是否为 偶数
            if (i%2==0) {
   
                //count + 1
                count++;
                //打印内容
                System.out.print(i+",");
            }
            //判断 count 是否等于 5
            if (count == 5) {
   
                // 重新赋值为0
                count = 0;
                //换行
                System.out.println();
            }
        }
    }
}
public class Test {
   
    public static void main(String[] args) {
   
        //小明有20块钱,去买可乐,一瓶可乐3块,每个瓶盖可以抵1块,问小明可以喝多少瓶可乐。
        //用户输入金额,输入喝饮料金额,查看能喝多少瓶
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入金额》》》");
        int sum = sc.nextInt();
        System.out.println("请输入饮料价格》》》");
        int num = sc.nextInt();

        //区间次数
        int count = 0;
        //总次数
        int count2 = 0;

        //循环判断,用户可以买几瓶
        while (sum>num) {
   
            //计算购买次数
            count = sum / num;
            //将次数赋值给总次数
            count2 += count;
            //获取剩余的钱 + 购买次数
            sum = sum % num + count;
        }
        System.out.println(count2);
    }
}
public class Test {
   
    public static void main(String[] args) {
   
        /*
        *   九九乘法表,一共九层
        *   每层都是从1开始计算,直到当前层数
        *   1*1=1
        *   1*1=1 1*2=2
        *   1*1=1 1*2=2 1*3=3
        */
        //外层循环控制次数
        for (int i = 1;i<=9;i++) {
   
            //里面循环,进行计算和打印
            for (int j = 1;j<=i;j++) {
   
                System.out.print(j + "*" + i + "=" + (i*j) + "\t");
            }
            //换行
            System.out.println();
        }
    }
}

执行顺序

  1. 初始化变量
  2. 判断条件,条件为 true,则执行一次,条件变更,依次执行
  3. 条件为 false 时,则循环终止,执行后续代码

注意事项

  1. 在死循环下面,写程序会报错,因为程序不可达
  2. for 循环和 while 循环很像,for 循环能做的事情,while 也能做,只不过使用场景不同
  3. 将初始值写在 for 循环的括号里,减少内存的开支,而且初始变量的作用范围也缩小了
  4. 循环可以嵌套
3.6.3 break 和 continue
3.6.3.1 break

break 跳出当前循环

public class Test {
   
    public static void main(String[] args) {
   
        //循环1~100
        for (int i = 1;i<=100;i++) {
   
            //输出循环次数
            System.out.println(i);
            //i == 50
            if (i == 50) {
   
                //跳出循环
                break;
            }
        }
    }
}
3.6.3.2 continue

continue 跳过本次循环,执行下一次

public class Test {
   
    public static void main(String[] args) {
   
        //循环1~100
        for (int i = 1;i<=100;i++) {
   
            //判断
            if (i%2==0) {
   
                //跳出本次循环继续下一次
                continue;
            }
            //如果 i 是基数,则打印输出
            System.out.println(i);
        }
    }
}

3.7 方法

3.7.1 方法是什么?

方法就是一段特殊功能代码的集合,它里面封装了特殊功能的代码,从而达到复用性

3.7.2 方法的使用

语法

修饰符 [static] {
   void|数据类型} 方法名(形参1,形参2) {
   
    方法体
    [return |数据类型;]
}

// 修饰符 表示当前方法的访问权限
// static 静态、唯一、共享,属于类
// void 无返回数据类型
// 数据类型 表示你要返回那些数据类型,数据类型可以是基本数据类型,也可以是引用数据类型
// 方法名 相当于人的名字,用于寻找方法
// 参数 可以理解,传递的数据,这些数据是有数据类型的
// return 终止程序,返回内容

示例

public class Test02 {
   
    // 这是一个无参的方法
    public static void test01() {
   
        for (int i = 1;i<=9;i++) {
   
            for (int j = 1;j<=i;j++) {
   
                System.out.print(j+"*"+i+"="+(j*i)+"\t");
            }
            System.out.println();
        }
    }

    /*
    *   有参方法的参数,是根据现实的业务需求来决定的
    *   比如:我要写一个能够实现三位操作数的加法运算的方法
    *       首先三位操作数,是不是就对应者三个变量
    *       那么方法中,就要定义三个形参
    *   注意:
    *       1、方法中参数,被称为形参,实际传入的值,被称为实参
    *       2、方法中参数,相当于我们之前定义的变量,只不过方法参数的值,是谁调用,有谁来赋值
    *       3、方法中参数,可以定义一个或多个,参数是有数据类型的,参数定义完成后,是有顺序的
    *           在调用方法时,传入参数就要遵循方法参数的数据类型和顺序
    */
    public static void add(int num,double num2,long num3) {
   
        System.out.println(num+num2+num3);
    }

    public static void main(String[] args) {
   
        //无参方法的调用:方法名();
        test01();

        /*
        *   有参方法的调用:方法名(参数值1,参数值2....)
        *   方法的参数,定义了多少个就要传递多少个,且数据类型和顺序不能乱
        */
        add(20,36.5d,60L);
    }
}

注意事项

  1. 方法的类型有:无参方法和有参方法

  2. 有参方法中的参数,一旦定义,在调用传值时,就必须遵循其顺序和数据类型

  3. 方法中的参数,是调用者负责传参的

  4. 有参方法中的参数,可以定义一个或多个,具体还是根据业务需求来决定的

3.7.3 方法的返回值

示例

public class Test {
   
    //计算两数之和,并*2,将其打印出来
    public static void add(int num,int num2) {
   
        System.out.println((num+num2)*2);
    }

    //计算三数之和,并*2,将其结果返回
    public static int add2(int num,int num2,int num3) {
   
        return (num+num2+num3)*2;
    }

    public static void main(String[] args) {
   
        add(10,20);
        System.out.println(add2(20,10,25));
    }
}

注意事项

  1. 当方法带有 void 表示,此方法无返回值

  2. 如果我们要方法执行完毕后,向调用者返回一个内容,那么就需要返回值

  3. 返回的数据类型是什么,void 就要被替换成什么类型,return 就要返回什么类型

  4. 方法什么时候,需要返回值?什么时候不需要?

    • 看业务需求,看调用者是否需要方法返回一个值,进行操作
  5. 当方法中带有 void ,我们仍然可以使用 return ,只不过不能返回任何数据

    public static void add() {
         
        return;
    }
    
3.7.4 方法的重载
  • 方法的重载就是:同类,不同操作

  • 两同

    • 同名、同类
  • 三不同(参数列表)

    • 个数不同
    • 顺序不同
    • 类型不同
  • 方法的重载与返回值和方法名无关

  • 方法重载参数类型匹配机制

    • 先匹配,自身数据类型
    • 方法的重载方式
  • 示例

  • public class Test {
         
        public static int add(int num,int num2) {
         
            return num+num2;
        }
        //个数不同
        public static int add(int num,int num2,int num3) {
         
            return num+num2+num3;
        }
        //类型不同
        public static int add(double num,int num2) {
         
            return (int)num+num2;
        }
        //顺序不同
        public static int add(int num,double num2) {
         
            return num+(int)num2;
        }
        //返回值不同,不够成重载
    //    public static double add(int num,double num2) {
         
    //        return 0.0d;
    //    }
        //数据类型相同,变量名不同,不构成方法的重载
    //    public static double add(int a,double b) {
         
    //        return 0.1d;
    //    }
    }
    
3.7.5 练习
  • 示例

  • public class Test {
         
        //返回水仙花数
        public static int test01(int num) {
         
            //计算数字的长度
            int length = length(num);
            //存储数字
            int num2 = num;
            //存储累加和
            int sum = 0;
            //循环计算吧
            while(num != 0) {
         
                //获取最后一位
                int bit = num%10;
                //计算 当前数^length 平方之和,进行累加
                sum += pow(bit,length);
                //移除最后一位
                num /= 10;
            }
            //判断是否是水仙数
            if (sum == num2) {
         
                return sum;
            }
            //不是就返回 0
            return 0;
        }
    
        //将一个数,倒叙输出
        public static void test02(int num) {
         
            //获取数字的长度
            int length = length(num);
            //存储累加和
            int sum = 0;
            //循环,计算
            for (int i = 1;i<=length;i++) {
         
                //获取最后一位
                int bit = num%10;
                //计算 bit * 10^length - 当前位数
                sum += (bit*(length-i==0?1:pow(10,(length-i))));
                //移除最后一位
                num /= 10;
            }
            //打印输出
            System.out.println(sum);
        }
    
        //根据用户输入的金额和饮料的单价,来判断总金额可以买几瓶
        public static void test03(int num,int num2) {
         
            //区间记录购买次数
            int count = 0;
            //总记录购买次数
            int count2 = 0;
            //循环,计算
            while (num>num2){
         
                //总金额 / 单价,获取购买次数
                count = num / num2;
                //将区间的购买次数,赋值给总购买次数
                count2 += count;
                //获取剩余的金额,加上购买次数
                num = (num % num2) + count;
            }
            //打印输出
            System.out.println(count2);
        }
    
        //用户输入年月日,判断当前年的时间离当前年的初始第一天,距离多少天
        public static void dateDay() throws InputMismatchException{
         
            //创建 Scanner 对象
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入年份");
            int year = scanner.nextInt();
            System.out.println("请输入月份");
            int month = scanner.nextInt();
            System.out.println("请输入日期");
            int day = scanner.nextInt();
            //定义总天数
            int maxDay = 0;
    
            //获取当前月份之前的天数
            for (int i = 1;i<day;i++) {
         
                //偶数月为30,基数月为31
                if (i%2==0) {
         
                    maxDay += 30;
                }else {
         
                    maxDay += 31;
                }
            }
            //判断是否是闰年,还是平年
            //闰年(1)年份能被4整除,但不能被100整除;(2)能被400整除
            //闰年 2 月 29天,平年 2 月 28 天
            if (((year % 4 == 0) && year % 100 != 0)||year % 400 == 0) {
         
                maxDay -= 1;
            }else {
         
                maxDay -= 2;
            }
            //打印天数
            System.out.println(maxDay);
        }
    
        //键盘输入,并将结果返回
        public static int scannerIn() {
         
            //创建 Scanner 对象
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入数字");
            //判断输入的内容是否是数字
            if (!scanner.hasNextInt()) {
         
                //抛出错误
                throw new InputMismatchException("请正确输入内容");
            }
            return scanner.nextInt();
        }
    
    
        //计算平方之和的方法,并将数字返回
        public static int pow(int num,int pow) {
         
            //接受数字
            int rest = num;
            //循环,计算平方和
            for (int i = 1;i<pow;i++) {
         
                //rest = rest * num;
                rest *= num;
            }
            //返回内容
            return rest;
        }
    
        //计算数字长度的方法,将数字的长度返回
        public static int length(int num) {
         
            //记录次数
            int index = 0;
            //循环,计算
            while(num != 0) {
         
                num /= 10;
                index++;
            }
            //返回内容
            return index;
        }
        public static void main(String[] args) {
         
    //        System.out.println(test01(153));
    //        test02(103456);
    //        test03(20,3);
              dateDay();
        }
    }
    
  • 注意事项

    • 方法在定义时,先结果,再过程
    • 减少代码的冗余,判断业务中,是否有其他代码和此方法中的逻辑一样,如一样,提出来,单独写个方法
    • 简化代码,排除错误
    • 可以试着将方法中其他逻辑查分,由当前方法调用

3.8 递归

递归是什么?

​ 递归就是自己调用自己,递归分为递归头和递归体。

​ 递归头就是判断程序什么时候结束,递归体就是执行的逻辑代码。

​ 递归一般用于打印 结构,其他的不怎么常用

​ 递归语法简单,但是十分耗内存资源

示例

public class Test {
   
    //计算斐波那契数列
    public static int test01(int num) {
   
        if (num == 1||num == 2) {
   
            return 1;
        }
        return test01(num-1)+test01(num-2);
    }
    //计算阶乘
    public static int test02(int num) {
   
        if (num == 1) {
   
            return 1;
        }
        return num*(num-1);
    }
}

第四章 面向对象

4.1 什么是面向过程?

  • 面向过程是执行者思维

  • 面向过程是按照步骤去执行?

  • 我们开车回家?那么开车回家有哪些步骤?

    • 开门,进车
    • 插上钥匙,启动
    • 确定路线,出发
    • 将车停机停车场
    • 下车,回家
  • 面向过程虽然是按照步骤去执行的,但是很多时候都是从无到有(根据事情不同)

  • 所以面向过程只适合做简单的事情,面对复杂的事情,反而会很困难

4.2 什么是面向对象?

  • 面向对象是设计者思维,更加贴合人的语言和人的逻辑
  • 那么它是如何去工作的?
  • 比如造车?车由哪些部分组成?
    • 轮胎
    • 发动机
    • 座椅
    • 玻璃
    • 车壳
  • 首先面向对象不会去管,这些东西是什么生产的,它会将这些东西交给不同的厂商去生产,进行组成,就 ok 了
  • 如果这些东西你要让面向过程去做?是不是很复杂的
  • 所以面向对象适合处理复杂且多人协作的事情

4.3 面向过程和面向过程的总结

  • 都是解决问题的思路

  • 宏观上面向对象负责整体的架构设计

  • 微观上面向过程负责去执行和调用

  • 所以面向对象离不开,面向过程

  • 而面向过程不需要面向对象

4.4 类和对象的关系

4.4.1 什么是类?
  • 类可以看做是一个现实事物的模板,也可以看做是虚拟事物的模板

  • 类具有现实事物的属性和行为

  • 比如人?图解

请添加图片描述

  • 类可以包含

    • 属性(变量)
      • 成员属性
      • 静态属性
    • 方法
    • 方法
      • 成员方法
      • 静态方法
    • 构造方法
  • 什么是成员变量和成员方法?

    • 在方法之外,类之内里面的变量和方法
    • 没有被 static 修饰的属性和方法
    • 成员属性和成员方法属于对象,只能通过对象来调用
  • 成员属性的默认值

    • 整数类型:0
    • 字符类型:空字符
    • 布尔类型:false
    • 浮点型:0.0
    • 引用类型:null
  • 局部变量

    • 局部变量就是指在方法中定义的变量,也就是方法中 { } 中定义的变量
4.4.2 什么是对象
  • 类可以看做是现实事物和虚拟事物的模板

  • 那么对象就可以看做是这个模板具体实现,同时也是一个具体事物的实现

  • 类就是对象的模板,我们通过这个模板,定义n个对象

  • 示例

    //定义一个学生类
    public class Student {
         
        //姓名
        public String name;
        //年龄
        public int age;
        //性别
        public char sex;
        //专业
        public String major;
        //学校
        public String school;
        //班级
        public String classs;
    
        public void eat() {
         
            System.out.println("吃饭");
        }
        public void sun() {
         
            System.out.println("运动");
        }
        public void study() {
         
            System.out.println("学习");
        }
        public void homework() {
         
            System.out.println("写作业");
        }
    
        public static void main(String[] args) {
         
            //创建对象
            //类名 变量名 = new 类名();
            Student student = new Student();
            //调用方法
            student.eat();
            student.study();
            //调用属性,赋值
            student.name = "小丁";
            student.age = 20;
            student.sex = '男';
            //打印属性
            System.out.println(student.name);
        }
    }
    

4.5 构造器

4.5.1 什么是构造器?
  • 构造器也叫构造方法,用于初始化对象,并给对象属性赋值
  • 创建对象时,默认调用无参构造器,目的是对象的初始化
  • Java 通过 new 关键字来调用构造器,从而返回该类的实例
4.5.2 构造器的分类
  • 无参构造(默认创建)
  • 有参构造
4.5.3 构造器的语法
//无参构造
public 类名() {
   
    
}
//有参构造
public 类名(属性1,属性2...){
   
    this.属性1 = 属性1;
    this.属性2 = 属性2;
}
4.5.4 构造器的使用
public class Dog {
   
    public String name;
    public int age;
    public char sex;

    //无参构造器,在对象创建是默认调用,前提是无参对象
    public Dog() {
   
        System.out.println("调用了无参构造方法");
    }
    //有参对象
    public Dog(String name,int age,char sex) {
   
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    public void behavior() {
   
        System.out.println("摇尾巴");
    }

    public static void main(String[] args) {
   
        //无参对象,在创建对象时,默认调用无参构造方法
        Dog dog = new Dog();
        //有参构造
        Dog dog2 = new Dog("小黄",20,'男');
        System.out.println(dog);
    }
}

注意事项

  1. 无参构造器,不需要创建,在创建无参对象时,默认调用
  2. 有参构造器一旦创建,默认构造器就不会在自动创建了
  3. 建议,编写类时,手动把无参构造器写上
  4. 构造器通过 new 关键字调用!
  5. 构造器虽然有返回值,但是不能指定其返回类型(返回值的类型是本类),不能在构造器里面使用 return 返回某个值,但可以使用 return;
  6. 构造的方法名必须和类名一样

对象的创建是由构造方法实现的吗?

  1. 不安全是,构造是 Java 创建对象的重要途径之一,在调用 new 关键字时,确实返回该类的实例,但是对象的创建,并不完全是由构造器实现的
  2. 对象的创建分为一下几个步骤
    • 分配对象空间,并将对象成员变量初始化为0 会 null
    • 执行属性值的显示初始化
    • 执行构造方法
    • 返回对象的地址给相关的变量
4.5.5 构造器的重载
  • 我们可以根据需求,来对象相应的属性赋值

  • public class Dog {
         
        public String name;
        public int age;
        public char sex;
    
        //无参构造器,在对象创建是默认调用,前提是无参对象
        public Dog() {
         
            System.out.println("调用了无参构造方法");
        }
        //有参构造器1
        public Dog(String name,int age,char sex) {
         
            this.name = name;
            this.age = age;
            this.sex = sex;
        }
        //有参构造器2
        public Dog(String name,int age) {
         
            this.name = name;
            this.age = age;
        }
        //有参构造器3
        public Dog(int age,char sex) {
         
            this.age = age;
            this.sex = sex;
        }
    
        public void behavior() {
         
            System.out.println("摇尾巴");
        }
    
        public static void main(String[] args) {
         
            //创建对象
            Dog dog = new Dog("小黄",2,'雄');
            Dog dog2 = new Dog("狗蛋",3);
            Dog dog3 = new Dog(1,'雌');
            //打印内容
            System.out.println(dog.name + ","+dog.age + "," + dog.sex);
            System.out.println(dog2.name + "," + dog2.age + "," +dog2.sex);
            System.out.println(dog3.name + "," + dog3.age + "," + dog3.sex);
        }
    }
    

注意事项

  1. this 表示当前对象

  2. 当构造器里面的形参名与属性名一致时,需要使用 this 进行指定哪个是对象的属性,哪个是形参

    public class Dog() {
         
        public int age;
        public Dog(int age) {
         
            //this.age 表示当前对象的属性,age表示构造的形参
            this.age = age;
        }
    }
    

4.6 值的传递机制

  • 基本数据类型,在传递值时,传递的是副本数据,其值不会发生改变

  • 引用类型,在传递值时,传递的是地址,如果对这个地址做了一些操作,外面的那个引用类型的值会发生改变

  • public class Test {
         
        //基本数据类型,在传递值时,传递的是副本数据,其值不会发生改变
        public void test01(int num) {
         
            num += 10;
            System.out.println("里面num的值:"+num);
        }
        //引用类型,在传递值是,传递的是地址,如果方法对这个地址做出改变,那么外面那个引用类型的值会发生改变
        public void test02(int[] arry) {
         
            //将数据内容的值位置对换
            for (int i = 0;i<arry.length/2;i++) {
         
                //获取当前索引值
                int num2 = arry[i];
                //获取 arry.length - (i+1) 索引的值
                arry[i] = arry[arry.length - (i+1)];
                //将 num2 的值 赋值给 arry.legnth - (i+1)的索引
                arry[arry.length - (i+1)] = num2;
            }
            //打印内容
            System.out.println("里面arry数组的内容:"+Arrays.toString(arry));
        }
    
        public static void main(String[] args) {
         
            //创建 Test 对象
            Test test = new Test();
            //定义基本数据类型
            int num = 10;
            //定义数据
            int[] arry = {
         1,2,3,4,5,6,7,8,9,10};
    
            //调用基本数据类型,传值的方法
            test.test01(num);
            System.out.println("外面num的值:"+num);
    
            //调用引用类型,传值的方法
            test.test02(arry);
            System.out.println("外面arry数组的值:" + Arrays.toString(arry));
        }
    }
    

4.7 垃圾回收机制

4.7.1 垃圾回收机制介绍
  • 每个程序员都遇到过内存溢出的情况,程序运行时,内存空间是有限的,那么如何及时的把不再使用的
    对象清除将内存释放出来,这就是GC要做的事。
  • 说起垃圾回收机制(GC),大部分人都把这项技术当做Java语言的伴生产物。事实上,GC的历史比Java
    久远,早在1960年Lisp这门语言中就使用了内存动态分配和垃圾回收技术
  • 程序员们知道,jvm内存结构分为五大区域:程序计数器、虚拟机栈、本地方法栈、堆区、方法区
  • 其中虚拟机栈、本地方法栈与程序计数器这3个区域随线程而生、随线程而灭,因此就不需要考虑过多内存垃圾回收问题,因为一个方法调用结束或者线程结束时,内存自然就跟随着回收了
  • 我们就把重点放在方法区与堆区,这部分内存的分配和回收是动态的,正是垃圾收集器所需关注的部分
4.7.2 不用语言下对象空间的释放
  • 传统的C/C++语言,需要程序员负责回收已经分配内存。显式回收垃圾回收的缺点
    • 程序忘记及时回收,从而导致内存泄露,降低系统性能
    • 程序错误回收程序核心类库的内存,导致系统崩溃
  • Java语言不需要程序员直接控制内存回收,是由JRE在后台自动回收不再使用的内存,称为垃圾回收机制(Garbage Collection)
    • 可以提高编程效率
    • 保护程序的完整性
    • 其开销影响性能。Java虚拟机必须跟踪程序中有用的对象,确定哪些是无用的
4.7.3 垃圾回收机制的关键点
  • 垃圾回收机制只回收JVM堆内存里的对象空间

  • 对其他物理连接,比如数据库连接、输入流输出流、Socket连接无能为力

  • 现在的JVM有多种垃圾回收实现算法,表现各异

  • 垃圾回收发生具有不可预知性,程序无法精确控制垃圾回收机制执行

  • 可以将对象的引用变量设置为null,暗示垃圾回收机制可以回收该对象

  • 程序员可以通过System.gc()或者Runtime.getRuntime().gc()来通知系统进行垃圾回收,会有一些效果,但是系统是否进行垃圾回收依然不确定

  • 垃圾回收机制回收任何对象之前,总会先调用它的finalize方法(如果覆盖该方法,让一个新的引用变量重新引用该对象,则会重新激活对象)

  • 永远不要主动调用某个对象的finalize方法,应该交给垃圾回收机制调用

4.8 this 和 static 关键

4.8.1 this 关键字
  • this 表示当前对象

  • 在构造器中 this 表示当前对象,在普通方法中 this 表示 调用这个方法的对象

  • this 可以用于构造器的重载,必须位于构造器的第一行

    • 调用方法 this(形参值) 根据形参值区分构造器
  • 在方法中如定义其和成员属性名一致的变量,需要使用 [this|对象名|类名].属性,否则默认就近原则

  • 构造器之间不能相互调用

  • public class TestThis {
         
        public static void main(String[] args) {
         
            //创建对象
            Dog dog = new Dog("小丁",25,'男');
        }
    }
    class Dog {
         
        public String name;
        public int age;
        public char sex;
    
        public Dog() {
         
            System.out.println("执行了无参构造");
        }
        /*public Dog(String name,int age,char sex) {
            形参名与成员属性名一致,不使用 this 指定其对象属性名,则自己给自己赋值
            name = name;
            age = age;
            sex = sex;
        }*/
        public Dog(String name,int age) {
         
            //调用无参构造
            this();
            this.name = name;
            this.age = age;
            System.out.println("执行了有参构造1");
        }
        public Dog(String name, int age, char sex) {
         
            //调用有参构造
            this(name,age);
            this.sex = sex;
            System.out.println("执行了有参构造2");
        }
    }
    
4.8.2 static 关键字
4.8.2.1 static 介绍
  • 静态属于类,成员属于对象

  • static 只能修饰成员属性和方法

  • 被 static 修饰的成员属性和成员方法是静态的、唯一的、被所有实例共享的,隶属于类

  • static 方法,不能访问非 static 成员,想要访问必须通过对象名或者创建对象

  • 在类被加载时,会将被 static 修饰的成员变量和方法,在静态区中进行初始化

  • 被 static 修饰的属性和方法被称为 静态属性和静态方法 或者 类属性和类方法

  • 在成员方法中可以访问:静态属性和静态方法

  • 调用方式

    • [类名|对象名].[属性|方法]
  • this 不能在 static 方法中使用

  • public class TestStatic {
         
        public static void main(String[] args) {
         
            //创建对象
            Student stu = new Student();
            Student stu2 = new Student();
            //调用类属性和类方法
            Student.major = "Java开发";
            Student.eat();
            //通过对象调用类属性
            System.out.println(stu.major);
            System.out.println(stu2.major);
            //验证是否唯一
            stu.major = "阿里巴巴";
            System.out.println(stu.major);
            System<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值