原创

    【Over】Java 基础教程【一】

    内容概要:

    开启 Java 之门

    Java 语言概述

    什么是 Java 语言

    Java 语言是美国的 Sun 公司(Stanford University Network) 在 1995 年推出的高级的编程语言。所谓编程语言,是计算机的语言,人们可以使用编程语言对计算机下达命令,让计算机完成人们需要的功能。

    Java 语言发展史

    Java 发展史:
    1995年发布Java 1.0版本 1997年发布Java 1.1版本 1998年发布Java 1.2版本 2000年发布Java 1.3版本 2002年发布Java 1.4版本 2004年发布Java 1.5版本 2006年发布Java 1.6版本
    2009年 Oracle 甲骨文公司收购 Sun 公司 2011年发布Java 1.7版本(Oracle 公司发布)
    2014年发布Java 1.8版本 2017年发布Java 9.0版本 2018年发布Java 10版本 …

    Java 能干什么

    Java 语言主要应用在互联网程序的后台开发领域。常见的互联网程序比如天猫、京东、物流系统、网银系统等,以及服务器后台处理大数据的存储、查询、数据挖掘等也有很多应用。例如下图:

    计算机基础

    认识进制

    计算机中的数据不同于我们生活中的数据,在生活中,我们采用 十进制数 计数,而在计算机中,全部都采用了 二进制数 表示,它只包含 0、1 两个数,逢二进一。例如:1 + 1 = 10 。每一个 0 或者每一个 1 ,叫做一个 bit(比特)表示信息的最小单位

    进制转换方法:
    十进制数据转成二进制数据:使用除以 2 获取余数的方式 二进制数据转成十进制数据:使用 8421 编码的方式

    各种进制的表示形式

    public static void main(String[] args) {
        System.out.println("二进制100的大小:\t" + 0B100);          // 二进制表示形式前面加0B(B可以大写,也可以小写)
        System.out.println("八进制100的大小:\t" + 0100);           // 八进制表示形式前面加0
        System.out.println("十进制100的大小:\t" + 100);            // 十进制直接输出
        System.out.println("十六进制100大小:\t" + 0X100);          // 十六进制前面加0x(X可以大写也可以小写)
    }
    

    认识字节

    字节 是我们常见的计算机中 最小存储单元 。计算机存储任何的数据,都是以字节的形式存储,右键点击文件属性,我们可以查看文件的字节大小。8 个 bit 表示为 1 个字节 ,写成 1byte 或者 1B

    位与字节:
    位(bit):一个数字 0 或者一个数字 1,代表一位。 字节(Byte): 8 位是一个字节,这是数据存储的最小单位。
    计算机存储单位之间的转换:
    1 Byte = 8 bit 1 KB = 1024 Byte 1 MB = 1024 KB 1 GB = 1024 MB 1 TB = 1024 GB 1 PB = 1024 TB 1 EB = 1024 PB 1 ZB = 1024 EB 1 YB = 1024 ZB 1 BB = 1024 YB

    常用 DOS 命令

    MS-DOS(Microsoft Disk Operating System) ,作为 Java 语言的初学者,学习一些 DOS 命令,会非常有帮助。DOS 是一个早期的操作系统,现在已经被 Windows 系统取代,对于我们开发人员,目前需要在 DOS 中完成一些事情,因此就需要掌握一些必要的命令。

    相关操作命令
    进入 DOS 窗口WIN + R ,输入 cmd 回车
    切换盘符例如切换到 D 盘: D:
    进入文件夹cd 文件夹名称
    进入多级文件夹cd 文件夹1\文件夹2\文件夹3
    返回上一级cd ..
    直接回根路径cd \
    查看当前内容dir
    清屏cls
    退出exit

    开发环境搭建

    Java 虚拟机

    JVM(Java Virtual Machine): Java 虚拟机,简称 JVM ,是运行所有 Java 程序的假想计算机,是 Java 程序的运行环境,是 Java 最具吸引力的特性之一。我们编写的 Java 代码,都运行在其上。

    跨平台性: 任何软件的运行,都必须要运行在操作系统之上。 而我们用 Java 编写的软件可以运行在任何的操作系统上,这个特性称为 Java 语言的跨平台特性。该特性是由 JVM 实现的,我们编写的程序运行在 JVM 上,而 JVM 运行在操作系统上

    JRE 和 JDK

    JRE 和 JDK :
    1、JRE (Java Runtime Environment): 是 Java 程序的运行时环境,包含 JVM 和运行时所需要的类库。 2、JDK (Java Development Kit): 是 Java 程序开发工具包,包含 JRE 和编译器等开发工具。

    三者关系: JDK > JRE > JVM

    JDK 安装图解

    第一步: 下载 JDK ,这是 下载网址 ,如下图:

    第二步: 安装 JDK 。如下图:

    温馨小提示: 到此为止, JDK 安装结束,接下来需要配置环境变量,这样才能使用。 个人推荐配置: 开发工具: IDEAJDK 版本: 11 及以上版本

    JAVA_HOME 的配置

    首先 win + r 打开命令行,输入 sysdm.cpl ,结果如下图:

    然后一直点击 确定 即可。这样,Java 环境就安装配置好了。那么怎么查看呢?打开命令行,使用 java -version 查看版本。有如下结果,就代表环境配置好了,否则配置出错了。结果如下图:

    其他教程: 菜鸟教程之 Java 开发环境配置

    编写入门程序

    开发环境已经搭建完毕了,现在可以开发我们的第一个 Java 程序了。Java 程序开发三步骤:编写代码、编译、运行 。现在,我们来搞定 第一步: 编写代码 。在桌面新建一个 HelloWorld.java 文件,写入如下代码:

    public class HelloWorld {
        public static void main(String[] args) {
            // 在 IDEA 软件中,alt + 4 是 console 的快捷键
            System.out.println("******************************");
            System.out.println("Hello World!");
            System.out.println("This is my first Java program!");
            System.out.println("******************************");
        }
    }
    

    第二步: 编译 HelloWorld.java编译 是指将我们编写的 Java 源文件 翻译成 JVM 认识的 class 文件 。在这个过程中,编译器会检查我们所写的程序是否有错误,有错误就会提示出来,如果没有错误就会编译成功。打开命令行,执行如下命令即进行了编译。如下图:

    第三步: 运行代码运行 是指将 字节码文件 交给 JVM 去执行,这样,我们的程序就跑起来了。如下图:

    1、小提示: 上述使用命令行编译和运行代码挺麻烦的,了解一下就行了。以后用 IDEA 编译和运行,就不需要用命令行了。 2、关于 main 方法 main 方法: 称为主方法。写法是固定格式不可以更改。main 方法是程序的入口点或起始点,无论我们编写多少程序,JVM 在运行的时候,都会从 main 方法这里开始执行。这里要注意:不要写成 mian ,初学容易写错。

    Java 中的注释

    注释: 就是对代码的解释和说明。其目的是 让开发人员能够更加轻松地了解代码 。为代码添加注释,是十分必要的,它不影响程序的编译和运行。Java 中有三种注释方式 ,相关介绍如下:

    单行注释      # 单行注释以 // 开头换行结束,单行注释支持嵌套。
    
    多行注释      # 多行注释以 /* 开头,以 */ 结束,多行注释不支持嵌套。
    
    文档注释      # 文档注释以 /** 开始,以 */ 结束,文档注释也不支持嵌套。
    

    单行注释

    单行注释以 // 开头换行结束,单行注释支持嵌套。

    // 定义一个变量 key
    int key = 10;
    
    // 定义一个方法,实现两数相加
    public static void add(int a, int b){
        return a + b;
    }
    

    多行注释

    多行注释以 /* 开头,以 */ 结束,多行注释不支持嵌套。

    /* 
     * 定义一个变量 key
     */
    int key = 10;
    
    /* 定义一个方法,实现两数相加 */
    public static void add(int a, int b){
        return a + b;
    }
    

    文档注释

    文档注释以 /** 开始,以 */ 结束,文档注释也不支持嵌套。

    /**
     * 定义一个变量 key
     */
    int key = 10;
    
    /**
     * 定义一个方法,实现两数相加
     */
    public static void add(int a, int b){
        return a + b;
    }
    

    Java 关键字与标识符

    关键字

    关键字概念:
    关键字是指在程序中,Java 已经定义好的单词,具有特殊含义。

    关键字举例: 在入门案例中,出现的关键字有 publicstaticvoidclass 等,这些单词已经被 Java 提前定义好了,全部都是小写字母,在 notepad++ 中有特殊的颜色 。关键字比较多,不用死记硬背,学到哪里记到哪里即可。需要一次性了解的请自行百度。

    标识符

    标识符: 是指在程序中,我们自己定义内容。比如 类的名字方法的名字变量的名字 等等,都是标识符。在入门案例中,出现的标识符有类的名字: HelloWorld

    命名规则【硬性要求】:
    1、标识符可以包含英文字母 26 个(区分大小写)、0-9 数字、$(美元符号)和 _(下划线)。 2、标识符不能以数字开头。 3、标识符不能是关键字。
    命名规范【软性建议】:
    1、类名规范:首字母大写,后面每个单词首字母大写(大驼峰式)。 2、方法名规范:首字母小写,后面每个单词首字母大写(小驼峰式)。 3、变量名规范:小驼峰式。用 final 修饰的变量全部大写,多个单词用 "_" 分隔。

    Java 中的常量和变量

    常量概述及分类

    常量概念: 常量是 "不改变的量" ,在计算机程序运行时,不会被程序修改的量,即固定不变的数据。以下是常量的分类:

    | 类型 | 含有 | 举例 | | :--: | ---- | ---- | | 整数常量 | 所有的整数 | 0,1,567,-9 | | 小数常量 | 所有的小数 | 0.0,-0.1,2.55 | | 字符常量 | 单引号引起来,只能写一个字符,必须有内容 | 'a','好' | | 字符串常量 | 双引号引起来,可以写多个字符,也可以不写 | "A","Hello","你好" | | 布尔常量 | 只有两个值(流程控制中讲解) | true,false | | 空常量 | 只有一个值(引用数据类型中讲解) | null |

    常量练习

    public class Constant {
        public static void main(String[] args) {
            // 常量的概念:在程序运行期间,固定不变的量。
            // 1、字符串常量
            System.out.println("ABC");
            System.out.println("");
            System.out.println("XYZ");
    
            // 2、整数常量
            System.out.println(30);
            System.out.println(-500);
    
            // 3、浮点数/小数常量
            System.out.println(3.14);
            System.out.println(-2.5);
    
            // 4、字符常量
            System.out.println('A');
            System.out.println('6');
            System.out.println(' ');        // 代表空格字符
            /*System.out.println('');       // 两个单引号中间必须有且仅有一个字符,没有不行。
            System.out.println('AB');       // 两个单引号中间必须有且仅有一个字符,有两个不行。*/
    
            // 5、布尔常量:只有两种取值。true、false。
            System.out.println(true);
            System.out.println(false);
    
            // 6、空常量:null。代表没有任何数据。空常量不能直接用来打印输出。
            // System.out.println(null);
        }
    }
    
    

    变量概述及定义

    变量概念: 常量是固定不变的数据,那么在程序中可以变化的量称为 变量 。在数学中,可以使用字母代替数字运算,例如 x = 1 + 5 或者 6 = x + 5。同样,在程序中,也可以用字母保存数字的方式来进行运算,提高计算能力。比如用 x 保存 5,且 x 也可以保存 6,这样 x 保存的数据是可以改变的,也就是我们所讲的变量。Java 中要求 一个变量每次只能保存一个数据 ,必须要明确保存的数据类型。所以下一章节我们去了解一下 Java 中的数据类型。

    变量的定义:
    1、三要素:数据类型、变量名、数据值。 2、格式为:数据类型 变量名 = 数据值;

    变量练习

    定义所有基本数据类型的变量,代码如下:

    public class Variable {
        public static void main(String[] args) {
           // 变量概念:程序运行期间,内容可以发生改变的量。
            int num1;
            num1 = 10;
            System.out.println("num1 = " + num1);
            num1 = 20;
            System.out.println("num1 = " +num1);
    
            int num2 = 25;
            System.out.println("num2 = " +num2);
            num2 = 35;
            System.out.println("num2 = " +num2);
            System.out.println("===============");
    
            // 注意:右侧数值的范围不能超过左侧数据类型的取值范围
            // byte num4 = 400; // 右侧超出了 byte 数据范围,错误!
            byte num3 = 30;
            System.out.println("num3 = " + num3);
    
            short num5 = 50;
            System.out.println("num5 = " + num5);
    
            long num6 = 3000000000L;
            System.out.println("num6 = " + num6);
    
            float num7 = 2.5F;
            System.out.println("num7 = " + num7);
    
            double num8 = 1.2;
            System.out.println("num8 = " + num8);
    
            char zifu1 = 'A';
            System.out.println("zifu1 = " + zifu1);
            
            // char 可以存储中文
            zifu1 = '中';
            System.out.println("zifu1 = " + zifu1);
            
            // char 的范围是 0 --> 65535
            zifu1 = 100;
            System.out.println(zifu1);
    
            boolean var1 = true;
            System.out.println("var1 = " + var1);
            
            var1 = false;
            System.out.println("var1 = " + var1);
            
            boolean var2 = var1;
            System.out.println("var2 = " + var2);
        }
    }
    
    

    温馨小提示: 1、long 类型: 建议数据后加 大写 L 表示,不建议用小写,易混淆。 2、float 类型: 建议数据后加 大写 F 表示,不建议用小写,易混淆。 ***3、***整数默认为 int 类型。 ***4、***小数默认为 double 类型。

    变量的注意事项

    变量的注意事项:
    1、变量名称:在同一个大括号范围内,变量的名字不可以相同。 2、变量赋值:定义的变量,不赋值不能使用。

    变量的注意事项 相关代码如下:

    public static void main(String[] args) {
        /*int num1 = 10;    // 创建了一个新的变量,名叫 num1
        int num1 = 20;    // 又创建了另一个新的变量,名字也叫 num1,错误!*/
    
        /*int num4;    // 定义了一个变量,但是没有进行赋值
        System.out.println(num4);    // 直接使用打印输出就是错误的!
        System.out.println(num5);    // 在创建 num5 这变量之前,不能使用这个变量*/
        int num5 = 500;
        System.out.println(num5);
        {
            int num6 = 60;
            System.out.println(num6);
        }
        //System.out.println(num6); // 已经超出了大括号的范围,超出了作用域,变量不能再使用了
    
        // 同时创建了三个全都是 int 类型的变量
        int a, b, c;
        a = 10;
        b = 20;
        c = 30;
        System.out.println("a = " + a + "\tb = " + b + "\tc = " + c);
    
        // 同时创建三个 int 变量,并且同时各自赋值
        int x = 100, y = 200, z = 300;
        System.out.println("x = " + x + "\ty = " + y + "\tz = " + z);
    }
    

    数据类型和运算符

    数据类型分类

    Java 的数据类型分为两大类:
    基本数据类型:包括整数、浮点数、字符、布尔。 引用数据类型:包括类、数组、接口。

    Java 基本数据类型 可以概括为 四类八种 ,如下表所示:

    | 数据类型 | 关键字 | 内存占用 | 取值范围 | | :--: | ---- | ---- | ---- | | 字节型 | byte | 1 个字节 | -128~127 | | 短整型 | short | 2 个字节 | -32768~32767 | | 整型 | int(默认) | 4 个字节 | -2的31次方~2的31次方-1 | | 长整型 | long | 8 个字节 | -2的63次方~2的63次方-1 | | 单精度浮点数 | float | 4 个字节 | 1.4013E-45~3.4028E+38 | | 双精度浮点数 | double(默认) | 8 个字节 | 4.9E-324~1.7977E+308 | | 字符型 | char | 2 个字节 | 0-65535 | | 布尔类型 | boolean | 1 个字节(有争议) | true,false |

    我们使用代码把上面表格的内容显示出来:

    public static void main(String[] args) {
        // byte
        System.out.println("************************************************\n");
        System.out.println("基本类型:byte\t二进制位数:" + "|"+Byte.SIZE+"|");
        System.out.println("包装类:java.lang.Byte");
        System.out.println("最小值:Byte.MIN_VALUE=" + Byte.MIN_VALUE);
        System.out.println("最大值:Byte.MAX_VALUE=" + Byte.MAX_VALUE);
        System.out.println();
    
        // char
        System.out.println("************************************************\n");
        System.out.println("基本类型:char\t二进制位数:" + "|"+Character.SIZE+"|");
        System.out.println("包装类:java.lang.Character");
        // 以数值形式而不是字符形式将Character.MIN_VALUE输出到控制台
        System.out.println("最小值:Character.MIN_VALUE="+(int)Character.MIN_VALUE);
        // 以数值形式而不是字符形式将Character.MAX_VALUE输出到控制台
        System.out.println("最大值:Character.MAX_VALUE="+(int)Character.MAX_VALUE);
        System.out.println();
    
        // short
        System.out.println("************************************************\n");
        System.out.println("基本类型:short\t二进制位数:" + "|"+Short.SIZE+"|");
        System.out.println("包装类:java.lang.Short");
        System.out.println("最小值:Short.MIN_VALUE=" + Short.MIN_VALUE);
        System.out.println("最大值:Short.MAX_VALUE=" + Short.MAX_VALUE);
        System.out.println();
    
        // int
        System.out.println("************************************************\n");
        System.out.println("基本类型:int\t二进制位数:" + "|"+Integer.SIZE+"|");
    
        System.out.println("包装类:java.lang.Integer");
        System.out.println("最小值:Integer.MIN_VALUE=" + Integer.MIN_VALUE);
        System.out.println("最大值:Integer.MAX_VALUE=" + Integer.MAX_VALUE);
        System.out.println();
    
        // float
        System.out.println("************************************************\n");
        System.out.println("基本类型:float\t二进制位数:" + "|"+Float.SIZE+"|");
        System.out.println("包装类:java.lang.Float");
        System.out.println("最小值:Float.MIN_VALUE=" + Float.MIN_VALUE);
        System.out.println("最大值:Float.MAX_VALUE=" + Float.MAX_VALUE);
        System.out.println();
    
        // long
        System.out.println("************************************************\n");
        System.out.println("基本类型:long\t二进制位数:" + "|"+Long.SIZE+"|");
        System.out.println("包装类:java.lang.Long");
        System.out.println("最小值:Long.MIN_VALUE=" + Long.MIN_VALUE);
        System.out.println("最大值:Long.MAX_VALUE=" + Long.MAX_VALUE);
        System.out.println();
    
        // double
        System.out.println("************************************************\n");
        System.out.println("基本类型:double\t二进制位数:" + "|"+Double.SIZE+"|");
        System.out.println("包装类:java.lang.Double");
        System.out.println("最小值:Double.MIN_VALUE=" + Double.MIN_VALUE);
        System.out.println("最大值:Double.MAX_VALUE=" + Double.MAX_VALUE);
        System.out.println();
        System.out.println("************************************************");
    }
    
    

    Java 中的默认类型: 整数类型是 int , 浮点类型是 double 。 Java 引用数据类型: 这部分后面会涉及到,请往下阅读。

    数据类型转换

    Java 程序中要求参与计算的数据,必须要保证数据类型的一致性,如果数据类型不一致将发生 类型转换异常

    自动类型转换

    概念: 将取值范围小的类型自动提升为取值范围大的类型。 转换规则: 范围小的类型向范围大的类型提升,byte、short、char ‐‐> int ‐‐> long ‐‐> float ‐‐> double 。

    自动类型转换 代码演示如下:

    public class DataTypeConversion {
        public static void main(String[] args) {
            // 数据类型转换之隐式转换
            // 1、特点:代码不需要进行特殊处理,自动完成。
            // 2、规则:数据范围从小到大。
            int x1 = 3;
            byte b1 = 4;                 // byte 取值范围:-128~127
            x1 = x1 + b1;                // 这里的 b1 自动转换为 int
            System.out.println(x1);
            double num2 = 2.5F;
            System.out.println(num2);
    
            // 左边是float类型,右边是long类型,long --> float,范围是float更大一些,符合从小到大的规则,发生自动类型转换
            float num3 = 30L;
            System.out.println(num3);
        }
    }
    
    

    以下是一道 面试题 ,如下:

    public static void main(String[] args) {
        // 面试题:以下程序是否有问题,给出理由。
        byte b01 = 3;
        byte b02 = 4;
    
        System.out.println(b01);
        System.out.println(b02);
    
        byte b03 = b01 + b02;
        System.out.println(b03);
    
        byte b04 = 3 + 4;            // java 编译器有常量优化机制
        System.out.println(b04);
    
        // 问题解析:
        // 1、byte 与 byte (或short,char)进行运算的时候会自动提升为 int ,两个 int 类型相加的结果也是 int 类型
        // 2、b01 和 b02 是两个变量,变量存储的值是变化,在编译的时候无法判断里面具体的值,相加有可能会超出 byte 的取值范围
        // 3、程序是有错的,自己拿到 IDEA 上就知道了。
    }
    

    下面是有关 ASCll 码表 中字符与数字对应关系,例如 字符 0 对应 ASCll 码表中的 数字 48

    public class DataTypeChar {
        public static void main(String[] args) {
            // 数字和字符的对照关系表(编码表):
            // ASCII 码表:American Standard Code for Information Interchange,美国信息交换标准代码。
            // Unicode 码表:万国码。也是数字和符号的对照关系,开头0-127部分和ASCII完全一样,但是从128开始包含有更多字符。
            // 48 - '0'
            // 65 - 'A'
            // 97 - 'a'
    
            char zifu1 = '1';
            System.out.println(zifu1 + 0);    // 49
    
            char zifu2 = 'A';   // 其实底层保存的是65数字
            System.out.println(zifu2 + 0);    // 65
            
            char zifu3 = 'c';
            // 左侧是int类型,右边是char类型, char --> int,确实是从小到大,从而发生了自动类型转换
            int num = zifu3;
            System.out.println(num);          // 99
    
            char zifu4 = '中';
            System.out.println(zifu4 + 0);    // 20013
        }
    }
    

    强制类型转换

    强制类型转换 就是将 取值范围大的类型强制转换成取值范围小的类型 。比较而言,自动转换是 Java 自动执行的,而强制转换需要我们自己手动执行。强制类型转换格式: 数据类型 变量名 =(数据类型)被转数据值; 代码演示如下:

    public static void main(String[]args){
        //short类型变量,内存中2个字节
        short s = 1;
        
        // 将会出现编译失败,s 和 1 做运算的时候,1 是 int 类型,s 会被提升为 int 类型
        // s+1后的结果是int类型,将结果在赋值会short类型时发生错误short内存2个字节,int类型4个字节
        // 必须将 int 强制转成 short 才能完成赋值
        s = s + 1;    //编译失败
        s = (short)( s + 1 );    //编译成功
    }
    

    强制类型转换 的图解如下:

    public static void main(String[]args){
        // 数据类型转换之强制转换
        // 1. 特点:代码需要进行特殊的格式处理,不能自动完成。
        // 2. 格式:范围小的类型 范围小的变量名 = (范围小的类型) 原本范围大的数据;
        // 注意事项:
        // 1. 强制类型转换一般不推荐使用,因为有可能发生精度损失、数据溢出。
        // 2. byte/short/char这三种类型都可以发生数学运算,例如加法“+”.
        // 3. byte/short/char这三种类型在运算的时候,都会被首先提升成为int类型,然后再计算。
        // 4. boolean类型不能发生数据类型转换
        int x2 = 3;
        byte b2 = 4;
        b2 = (byte)(x2 + b2);        //b2=(byte)x2+b2;这种写法是会出错的
        System.out.println(b2);
    
        //00000000 00000000 00000000 10000010            130的二进制
        //10000010                                        -126补码
        //00000001                                        -1求反码
        //10000001                                        -126反码
        //11111110                                        -126原码
        byte b3 = (byte)(126 + 4);
        System.out.println(b3);
    
        //00000000 00000000 00000001 00101100            300的二进制
        //00101100                                      正数的原码反码和补码一样
        byte b4 = (byte)300;
        System.out.println(b4);
    
        System.out.println((char)('a' + 1));    //结果是b
        System.out.println("hello"+'a'+1);        //任何数据类型用+与字符串相连接都会产生新的字符串
        System.out.println('a'+1+"hello");      //98hello,因为有ASCII码表,a字符对应的是int类型的97
    }
    

    小提示:

    1. 浮点转成整数,直接取消小数点,可能造成数据损失精度。 2. int 强制转成 short 砍掉2个字节,可能造成数据丢失。

    各种运算符

    算术运算符

    | 算术运算符包括 | 中文解释 | | :--: | ---- | | + | 加法运算,字符串连接运算 | | - | 减法运算 | | * | 乘法运算 | | / | 除法运算 | | % | 取模运算,两个数字相除取余数 | | ++,- - | 自增自减运算(单独说) |

    算术运算符 代码演示如下:

    /**
     * 1. 运算符:进行特定操作的符号。例如:+
     * 2. 表达式:用运算符连起来的式子叫做表达式。例如:20 + 5。又例如:a + b
     * 3. 四则运算 ==>  加:+    减:-    乘:*    除:/
     * 4. 取模运算(取余数):% ,只有对于整数的除法来说,取模运算符才有余数的意义。
     * 5. 首先计算得到表达式的结果,然后再打印输出这个结果
     * 6. 复习一下除法公式:被除数 / 除数 = 商 ... 余数
     * 7. 对于一个整数的表达式来说,除法用的是整除,整数除以整数,结果仍然是整数。只看商,不看余数。
     * 8. 注意事项:一旦运算当中有不同类型的数据,那么结果将会是数据类型范围大的那种。
     */
    public class Operator {
        public static void main(String[] args) {
            // 两个常量之间可以进行数学运算
            System.out.println(20 + 30);
    
            // 两个变量之间也可以进行数学运算
            int a = 20;
            int b = 30;
            System.out.println(a - b);   // -10
    
            // 变量和常量之间可以混合使用
            System.out.println(a * 10);  // 200
    
            int x = 10;
            int y = 3;
    
            int result1 = x / y;
            System.out.println(result1);  // 3
    
            int result2 = x % y;
            System.out.println(result2);  // 余数【模】为 1
    
            // int + double --> double + double --> double
            double result3 = x + 2.5;
            System.out.println(result3);  // 12.5
        }
    }
    

    取模运算 比较特殊,具体的解释代码里都有,代码如下:

    public class Operator{
        public static void main(String[] args){
            // % --> 取模运算符
            // % 运算符结果的符号只和左边有关系,与右边无关
            // 任何一个正整数 %2 结果不是 0 就是 1 , 可以用来当作切换条件 
    
            System.out.println(10 / 3);            // 整数相除结果只能是整数
            System.out.println(10 / 3.0);          // 如果想得到小数,把其中一个数变成小数,另一个数在运算的时候会自动类型提升
            System.out.println(-6 % 5);
            System.out.println(13 % -5);
        }
    }
    
    // 输出结果:
    3
    3.3333333333333335
    -1
    3
    

    赋值运算符

    | 赋值运算符包括 | 中文解释 | | :--: | ---- | | = | 等于号 | | += | 加等于 | | -= | 减等于 | | *= | 乘等于 | | /= | 除等于 | | %= | 取模等 |

    赋值运算符 代码演示如下:

    public class Operator{
        public static void main(String[] args){
            // 赋值运算符 =
            int a1 = 3;        // 把右边的常量值赋值给左边的变量,左边必须是变量
    
            // 赋值运算符 +=
            a1 += 4;    // a1 = a1 + 4;
            System.out.println(a1);
    
            // 赋值运算符 -=
            a1 -= 5;    // a1 = a1 - 4;
            System.out.println(a1);
    
            // 赋值运算符 *=
            a1 *= 2;    // a1 = a1 * 4;
            System.out.println(a1);
    
            // 赋值运算符 /=
            a1 /= 2;    // a1 = a1 / 4;
            System.out.println(a1);
    
            // 赋值运算符 %=
            a1 %= 2;    // a1 = a1 % 4;
            System.out.println(a1);
        }
    }
    

    比较运算符

    | 比较运算符包括 | 中文解释 | | :--: | ---- | | == | 比较符号两边数据是否相等,相等结果是true。 | | != | 不等于符号,如果符号两边的数据不相等,结果是true。 | | > | 比较符号左边的数据是否大于右边的数据,如果大于结果是true。 | | >= | 比较符号左边的数据是否大于或等于右边的数据,如果大于等于结果是true。 | | < | 比较符号左边的数据是否小于右边的数据,如果小于结果是true。 | | <= | 比较符号左边的数据是否小于或等于右边的数据,如果小于等于结果是true。 |

    比较运算符 代码演示如下:

    public class Operator{
        public static void main(String[] args){
            // 比较运算符,也称为关系运算符
            // == , != , > , >= , < , <= 
            System.out.println(4 == 3);
            System.out.println(4 != 3);
            System.out.println(4 > 4);
            System.out.println(4 >= 4);
            System.out.println(4 < 3);
            System.out.println(4 <= 3);
        }
    }
    

    逻辑运算符

    逻辑运算符包括:相关说明

    && 短路与
    两边都是 true,结果是 true
    一边是 false,结果是 false
    短路特点: 符号左边是 false,右边不再运算

    || 短路或
    两边都是 false,结果是 false
    一边是 true,结果是 true
    短路特点: 符号左边是 true,右边不再运算

    ! 取反
    !true 结果是 false
    !false 结果是 true

    逻辑运算符 是用来连接两个布尔类型结果的运算符,运算结果都是布尔值 true 或者 false 。代码演示如下:

    public static void main(String[] args) {
        // 逻辑运算符(不支持短路运算)    &    |    ^(异或)
        // 逻辑运算符(支持短路运算)    &&    ||    !
        int a = 10;
        int b = 23;
        int c = 34;
        System.out.println("&\t" + (a > b & b < c));      // false,a > b 和 b < c 都会执行
        System.out.println("&&\t" + (a > b && b < c));    // false, 当 a > b 被判断为错误时,b < c 不执行
        System.out.println("|\t" + (a > b | b < c));      // true
        System.out.println("||\t" + (a > b || b < c));    // true
        System.out.println("^\t" + (a > b ^ b < c));      // 相同为 false,不相同为 true 。例如:1^1=0 0^0=0 1^0=1 0^1=1
        System.out.println("!\t" + !(a < b));
    }
    

    位运算符

    位运算符 主要针对二进制,它包括了:& 与| 或~ 非^ 异或<< 左移>> 右移 。从表面上看,位运算符 似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算,而位运算符主要针对两个二进制数的位进行逻辑运算 。下面详细介绍每个位运算符。相关代码演示如下:

    public static void main(String[] args) {
        // 位运算符    &    ^    |    ~(按位取反)
        // ^ 的特点:一个数据对另一个数据位异或两次,该数本身不变。
        System.out.println("^ = " + (5 ^ 10 ^ 10));   // 可利用此特点不通过第三者而达到交换两个数的目的
        System.out.println("6 & 2 = " + (6 & 2));
        System.out.println("6 ^ 2 = " + (6 ^ 2));
        System.out.println("6 | 2 = " + (6 | 2));
        System.out.println("~56 = " + (~56));
    
        // 位运算符:左移    <<    左移几位就乘以 2 的几次方
        System.out.println("12左移3位:\t" + (12 << 3));
        System.out.println("12左移5位:\t" + (12 << 5));
    
        // 位运算符:右移    >>        右移几位就除以 2 的几次幂
        System.out.println("16右移3位:\t" + (16 >> 3));
        System.out.println("128右移5位:\t" + (128 >> 5));
    }
    
    // 输出结果:
    6 | 2 = 6
    ~56 = -57
    12左移3位:   96
    12左移5位:   384
    16右移3位:   2
    128右移5位:  4
    

    三元运算符

    三目运算符 又称 条件运算符 ,是计算机语言(c,c++,java等)的重要组成部分。它是 唯一一个有 3 个操作数 的运算符,有时又被称为 三元运算符 。一般来说,三目运算符的结合性是右结合的。【————百度百科】

    三元运算符格式: 数据类型变量名 = 布尔类型表达式 ? 结果1 : 结果2

    三元运算符计算方式: 如果 布尔类型表达式 结果是 true,三元运算符整体结果为 结果1,然后把 结果1 赋值给变量。否则就把 结果2 赋值给变量。代码演示如下:

    public static void main(String[]args){
        int i = (1 == 2 ? 100 : 200);
        System.out.println(i);    // 200
    
        int j = (3 <= 4 ? 500 : 600);
        System.out.println(j);    // 500
    
        int max = getMax(31,32,33);
        System.out.println(max);
    }
    
    // 求三个整数中的最大值
    public static int getMax(int a , int b , int c ){
        return (a > b ? a : b) > c ? (a > b ? a : b) : c;
    }
    

    自增自减运算符

    自增自减运算符 的所有知识点都在下面的代码演示中,所以这里就不做过多的介绍,代码演示如下:

    /**
     * 自增运算符:++    自减运算符:--
     * 1. 基本含义:让一个变量涨一个数字1,或者让一个变量降一个数字1
     * 2. 使用格式:写在变量名称之前,或者写在变量名称之后。例如:++num ,也可以 num++
     * 3. 使用方式:
     *      1. 单独使用:不和其他任何操作混合,自己独立成为一个步骤。
     *      2. 混合使用:和其他操作混合,例如与赋值混合,或者与打印操作混合,等。
     * 4. 使用区别:
     *      1. 在单独使用的时候,前++和后++没有任何区别。也就是:++num;和num++;是完全一样的。
     *      2. 在混合的时候,有【重大区别】
     *          A. 如果是【前++】,那么变量【立刻马上+1】,然后拿着结果进行使用。    【先加后用】
     *          B. 如果是【后++】,那么首先使用变量本来的数值,【然后再让变量+1】。    【先用后加】
     * 5. 注意事项:只有变量才能使用自增、自减运算符。常量不可发生改变,所以不能用。
     */
    public static void main(String[] args) {
        int num1 = 10;
        System.out.println(num1); // 10
        ++num1;  // 单独使用,前++
        
        System.out.println(num1); // 11
        num1++;  // 单独使用,后++
        
        System.out.println(num1); // 12
        System.out.println("=================");
    
        // 与打印操作混合的时候
        int num2 = 20;
        // 混合使用,先++,变量立刻马上变成21,然后打印结果21
        System.out.println(++num2);  // 21
        System.out.println(num2);    // 21
        System.out.println("=================");
    
        int num3 = 30;
        // 混合使用,后++,首先使用变量本来的30,然后再让变量+1得到31
        System.out.println(num3++); // 30
        System.out.println(num3);   // 31
        System.out.println("=================");
    
        int num4 = 40;
        // 和赋值操作混合
        int result1 = --num4;  // 混合使用,前--,变量立刻马上-1变成39,然后将结果39交给result1变量
        System.out.println(result1); // 39
        System.out.println(num4);    // 39
        System.out.println("=================");
    
        int num5 = 50;
        // 混合使用,后--,首先把本来的数字50交给result2,然后我自己再-1变成49
        int result2 = num5--;
        System.out.println(result2); // 50
        System.out.println(num5);    // 49
        System.out.println("=================");
    
        int x = 10;
        int y = 20;
        // 11 + 20 = 31
        int result3 = ++x + y--;
        System.out.println(result3); // 31
        System.out.println(x); // 11
        System.out.println(y); // 19
    
        // 30++; // 错误写法!常量不可以使用++或者--
    }
    

    JShell 脚本工具

    JShellJDK9 的新特性,这部分是个了解内容,需了解请参考: JShell 工具

    流程控制语句

    流程控制概述

    在一个程序执行的过程中,各条语句的执行顺序 对程序的结果是有直接影响的。也就是说,程序的流程对运行结果有直接的影响。所以,我们必须清楚每条语句的执行流程。而且,很多时候我们要通过控制语句的执行顺序来实现我们要完成的功能。接下来介绍 三种流程控制结构

    顺序结构

    顺序结构 就是 从上到下依此执行 ,代码演示如下:

    public static void main(String[] args){
        // 顺序执行,根据编写的顺序,从上到下运行
        System.out.println("今天天气不错");
        System.out.println("挺风和日丽的");
        System.out.println("我们下午没课");
        System.out.println("这的确挺爽的");
    }
    

    选择结构

    选择结构两种形式: if 选择结构switch 选择结构 。接下来我们详细讲一下这两种选择结构的 异同点

    选择结构-if

    第一种格式:if
    if (关系表达式) {     语句体; }
    第一种格式执行流程:
    1、首先判断关系表达式,看其结果是 true 还是 false 2、如果是 true 就执行语句体;如果是 false 就不执行语句体 3、代码举例如下
    // 因为 8 比 3 更大,所以输出结果为 OK!
    public static void main(String[] args){
        if(8 > 3){
            System.out.println("OK!");
        }
    }
    
    第二种格式:if…else
    if (关系表达式) {     语句体1; } else {     语句体2; }
    第二种格式执行流程:
    1、首先判断关系表达式,看其结果是 true 还是 false 2、如果是 true 就执行语句体1;如果是 false 就执行语句体2 3、代码举例如下
    // 因为 8 比 10 更小,所以输出结果为 NO!
    public static void main(String[] args){
        if(8 > 10){
            System.out.println("OK!");
        } else {
            System.out.println("NO!");
        }
    }
    
    第三种格式:if…else if…else
    if (关系表达式1) {     语句体1; } else if (关系表达式2) {     语句体2; }... }else if(关系表达式n) {     语句体n; } else {     语句体n+1; }
    第三种格式执行流程:
    1、首先判断关系表达式1,看其结果是 true 还是 false 2、如果是 true 就执行语句体1;如果是 false 就继续判断关系表达式2,看其结果是 true 还是 false 3、如果关系表达式2是 true ,就执行语句体2 ,如果是 false 就继续判断关系表达式3,看其结果是 true 还是 false 4、…… 5、如果没有任何关系表达式为 true,就执行语句体n+1 6、案例演示如下

    综合案例: 学生成绩等级设计 ,指定考试成绩,判断学生等级。

    评分机制如下:
    优秀:90~100 很好:80~89 良好:70~79 及格:60~69 加油: 0~60
    public static void main(String[] args){
    
        Scanner scanner = new Scanner(System.in);
    
        while (true) {
    
            System.out.print("请输入一个整数:");
            int score = scanner.nextInt();
    
            if (score < 0 || score > 100) {
                System.out.println("你的成绩是错误的");
            } else if (score >= 90 && score <= 100) {
                System.out.println("你的成绩属于优秀");
            } else if (score >= 80 && score < 90) {
                System.out.println("你的成绩属于很好");
            } else if (score >= 70 && score < 80) {
                System.out.println("你的成绩属于良好");
            } else if (score >= 60 && score < 70) {
                System.out.println("你的成绩属于及格");
            } else {
                System.out.println("你的成绩属于需要再接再厉!");
            }
    
        }
    }
    

    选择结构-switch

    switch 语法格式:
    switch (表达式) {     case 常量值1:         语句体1;         break;     case 常量值2:         语句体2;         break;     ...     default:         语句体n+1;         break; }

    switch 语句执行流程: 首先 获取到表达式的值,然后 把这个值和 case 的常量值依次比较,一旦有对应的值,就会执行相应 case 的语句体。在执行的过程中,遇到 break 就会结束。最后 ,如果所有的 case 都和表达式的值不匹配,就会执行***default 语句体*** 部分,然后程序结束。代码演示如下:

    public static void main(String[] args) {
    
        // 定义变量,判断是星期几
        int weekday = 6;
    
        // switch 语句实现选择
        switch(weekday) {
            case 1:
                System.out.println("星期一");
                break;
            case 2:
                System.out.println("星期二");
                break;
            case 3:
                System.out.println("星期三");
                break;
            case 4:
                System.out.println("星期四");
                break;
            case 5:
               System.out.println("星期五");
               break;
            case 6:
                System.out.println("星期六");
                break;
            case 7:
                System.out.println("星期日");
                break;
            default:
                System.out.println("你输入的数字有误");
                break;
        }
    
    }
    

    小提示:

    switch 语句中 ,表达式的数据类型,可以是 byte,short,int,char,enum(枚举)JDK7 后可以接收 字符串

    case 的穿透性: 在 switch 语句中,如果 case 的后面不写 break ,将出现 穿透现象 ,也就是不会再判断下一个 case 的值,而是直接向后运行,直到遇到 break,或者整体 switch 结束。代码举例如下:

    public static void main(String[]args){
        int i = 5;
        switch(i){
            case 0:
                System.out.println("执行case0");break;
            case 5:
                System.out.println("执行case5");
            case 10:
                System.out.println("执行case10");
            default:
                System.out.println("执行default");
        }
    }
    
    // 输出结果
    执行case5
    执行case10
    执行default
    

    在上述程序中,执行 case5 后,由于没有 break 语句,程序会一直向后走 ,不会再判断 case,直接运行完整体 switch 或者遇到 break 才会结束。由于 case 存在穿透性,因此初学者在编写 switch 语句时,必须要写上 break 。

    循环结构

    循环结构 可以 在满足循环条件的情况下,反复执行某一段代码 ,这段被重复执行的代码被称为 循环体语句 。当反复执行这个循环体时,需要在合适的时候把循环判断条件修改为 false,从而结束循环,否则循环将一直执行下去,形成 死循环

    循环结构-for

    for 循环的格式:
    for (初始化表达式①; 布尔表达式②; 步进表达式④) {     循环体③ }
    for 循环的执行流程:
    1、执行顺序:①②③④ > ②③④ > ②③④ … 直到②不满足循环条件为止。 2、①负责完成循环变量初始化 3、②负责判断是否满足循环条件,不满足则跳出循环 4、③是具体执行的语句 5、④表示循环后,循环条件所涉及变量的变化情况

    代码演示如下:

    public static void main(String[] args){
        // 循环 10 次,输出 HelloWorld 10次。定义变量从 0 开始,循环条件为 x < 10
        for (int x = 0; x < 10; x++) {
            System.out.println("HelloWorld" + x);
        }
    }
    

    一个小案例: 使用循环,计算 1-100 之间的偶数和 。代码如下:

    public static void main(String[] args){
        // 1、定义一个初始化变量,记录累加求和,初始值为 0
        int sum = 0;
    
        // 2、利用 for 循环获取 1‐100 之间的数字
        for (int i = 1; i <= 100; i++) {
            // 3、判断获取的数组是奇数还是偶数
            if(i % 2 == 0){
                // 4、如果是偶数就累加求和
                sum += i;
            }
        }
    
        // 5、循环结束之后,打印累加结果
        System.out.println("sum: " + sum);
    }
    

    循环结构-foreach

    public static void main(String[] args) {
    
        int[] num = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        for (int i : num)    // 这就是 for 的增强,类似于自然语言 for each
            System.out.println(i);
    
    
        int[] numbers = {10, 20, 30, 40, 50};
        for (int x : numbers) {
            System.out.print(x);
            System.out.print(",");
        }
        System.out.print("\n");
    
    
        String[] names = {"James", "Larry", "Tom", "Lacy", "Bob", "Jobs"};
        for (String name : names) {
            if (name == "Larry")
                continue;    // 结束本次循环,开始下一次循环
            if (name == "Lacy")
                break;       // 结束所有循环,直接跳出
            System.out.print(name);
            System.out.print(",");
        }
        System.out.println("\n-----------------------------");
    
    
        for (int x = 10; x < 20; x = x + 1) {
            System.out.print("value of x : " + x);
            System.out.print("\n");
        }
        
    }
    

    循环结构-while

    while 循环的格式:
    初始化表达式① while (布尔表达式②) {     循环体③     步进表达式④ }
    while 循环的执行流程:
    1、执行顺序:①②③④ > ②③④ > ②③④ … 直到②不满足循环条件为止。 2、①负责完成循环变量初始化 3、②负责判断是否满足循环条件,不满足则跳出循环 4、③是具体执行的语句 5、④表示循环后,循环变量的变化情况

    代码演示如下:

    // while 循环实现打印 10次 HelloWorld
    public static void main(String[] args){
        // 定义初始化变量
        int i = 1;
    
        // 循环条件 i <= 10
        while(i <= 10){
            System.out.println("HelloWorld");
            // 步进表达式
            i++;
        }
    }
    

    一个小案例: 使用循环,计算 1-100 之间的和

    public static void main(String[] args){
        // 使用 while 循环实现
        // 定义一个变量,记录累加求和
        int sum = 0;
    
        // 定义初始化表达式
        int i = 1;
    
        // 使用 while 循环让初始化表达式的值变化
        while(i <= 100){
            // 累加求和
            sum += i;
            // 步进表达式改变变量的值
            i++;
        }
    
        // 循环结束之后,打印累加结果
        System.out.println("1‐100 的和是:" + sum);
    }
    

    循环结构-do…while

    do…while 循环的格式:
    初始化表达式① do {     循环体③     步进表达式④ } while(布尔表达式②);
    do…while 循环的执行流程:
    1、执行顺序:①②③④ > ②③④ > ②③④ … 直到②不满足循环条件为止。 2、①负责完成循环变量初始化 3、②负责判断是否满足循环条件,不满足则跳出循环 4、③是具体执行的语句 5、④表示循环后,循环变量的变化情况

    代码演示如下:

    // while 循环实现打印 10 次 HelloWorld
    public static void main(String[] args){
        // 定义初始化变量
        int i = 1;
    
        // 循环条件 i <= 10
        do {
            System.out.println("HelloWorld");
            // 步进表达式
            i++;
        } while(i <= 10);
    }
    

    注意: do…while 循环中的 while 后面有分号哦,可不要忘记了。

    do...while 循环的特点: 无条件执行一次循环体,即使我们将循环条件直接写成 false ,也依然会循环一次。这样的循环具有一定的风险性,因此不太建议使用 do...while 循环,推荐使用 for 循环和 while 循环

    public static void main(String[] args){
        do {
            System.out.println("无条件执行一次");
        } while(false);
    }
    

    接下来演示一个 do…while 版的 9 * 9 乘法口诀表 小案例,代码演示如下:

    public static void main(String[] args) {
        int i = 1;      //外循环变量定义在外面
        do {
    
            int j = 1;  // 内循环变量定义在第一个 do…while 里面
    
            do {
                System.out.printf("%d * %d = %d\t", i, j, i * j);
                j++;
            } while (j <= i);
    
            System.out.println();
            i++;
    
        } while (i <= 9);
    }
    

    扩展知识点

    break 和 continue

    • break 使用场景: 跳出循环,只能在 switch循环语句 中使用
    public static void main(String[] args){
        for (int i = 1; i <= 10; i++) {
            // 打印完两次 HelloWorld 就结束循环
            if(i == 3){
                break;
            }
            System.out.println("HelloWorld" + i);
        }
    }
    
    • continue 使用场景: 结束本次循环,继续下一次的循环。只能在 循环语句 中使用
    public static void main(String[] args){
        for(int i = 1;i <= 10;i++){
            // 不打印第三次 HelloWorld
            if(i == 3){
                continue;
            }
            System.out.println("HelloWorld" + i);
        }
    }
    

    死循环

    死循环: 也就是循环中的条件永远为 true ,死循环是永不结束的循环 。例如:while(true){} 。在后期的开发中,会出现使用死循环的场景。例如:我们需要读取用户输入的输入,但是用户输入多少数据我们并不清楚,也只能使用死循环,当用户不想输入数据了,就可以结束循环了,如何去结束一个死循环呢,就需要使用到跳出语句了。代码演示如下:

    // 以下是三种循环的死循环
    public static void main(String[] args) {
    
        // 以下是 for 的死循环,去掉 break 就是死循环
        for ( ; ; ) {
            System.out.println("I LOVE YOU!");
            break;
        }
    
    
        // 以下是 do~while 的死循环,去掉 break 就是死循环
        do {
            System.out.println("HOPE IS BEAUTIFUL!");
            break;
        } while(true);
    
    
        // 以下是 while 的死循环
        while (true) {
            System.out.println("SHAPE OF YOU!");
        }
    
    }
    

    嵌套循环

    嵌套循环 是指一个循环的循环体是另一个循环。比如 for 循环里面还有一个 for 循环 ,就是 嵌套循环 。当然也可以嵌套多层,而且不同的循环结构相互之间也可以嵌套。循环次数: 总共的循环次数 = 外循环次数 * 内循环次数

    嵌套循环格式举例:
    for (初始化表达式①; 循环条件②; 步进表达式⑦) {     for (初始化表达式③; 循环条件④; 步进表达式⑥) {         执行语句⑤;     } }
    嵌套循环执行流程:
    1、执行顺序:①②③④⑤⑥ > ④⑤⑥ > ⑦②③④⑤⑥ > ④⑤⑥ 2、外循环一次,内循环多次。比如跳绳:一共跳5组,每组跳10个。5组就是外循环,10个就是内循环。

    嵌套循环练习: 使用嵌套循环,打印 58 的矩形* 。实现代码如下:

    // 5*8 的矩形,打印5行*号,每行8个
    public static void main(String[] args){
        // 外循环 5 次,内循环 8 次
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 8; j++) {
                // 不换行打印星号
                System.out.print("*");
            }
            // 内循环打印 8 个星号后,需要一次换行
            System.out.println();
        }
    }
    

    开发工具和方法

    开发工具概述

    我们常用的 Java 开发工具EclipseNetBeansIDEA 等等。这里只介绍 IDEA因为是世界上用的最多的 。 IDEA 是一个专门针对 Java 的集成开发工具(IDE),由 Java 语言编写。所以需要有 JRE 运行环境并配置好环境变量 ,它可以极大地提升我们的开发效率。在公司中,使用的就是 IDEA 进行开发。具体的安装和使用请参考: IDEA 入门教程

    Java 中的方法

    方法的概述

    在学习运算符的时候,需要为每个运算符单独地创建一个新的类。这时我们发现,这样编写代码是非常的繁琐,而且重复的代码过多。能否避免这些重复的代码呢?当然可以,使用方法来实现。方法: 在 C 语言中称之为 函数 ,就是将一个功能抽取出来,把代码单独定义在一个大括号内,形成一个单独的功能。当我们需要这个功能的时候,就可以去调用。这样即实现了代码的复用性,也解决了代码冗余的现象

    方法的格式:
    修饰符 返回值类型 方法名 (参数列表){     方法体     return 返回值; }
    方法的格式的解释:
    修饰符:目前固定写法 public static 返回值类型:基本数据类型和引用数据类型 方法名:为我们定义的方法起名,满足标识符的规范,用来调用方法。 参数列表:可以空参,也可以有参 return:方法结束。如果返回值类型是 void ,方法大括号内的 return 可以不写。其他情况一律需要返回值。

    代码演示如下:

    // 定义 twoSum 方法,实现两个整数相加
    public static void twoSum(int a , int b){
        System.out.println("两数之和为:" + (a + b));
    }
    

    方法定义的两个明确

    举例说明: 定义方法实现 两个整数的求和计算 。需要明确的两件事如下:

    明确返回值类型:
    方法计算的是整数的求和,结果也必然是个整数,所以返回值类型定义为 int 类型。
    明确参数列表:
    计算哪两个整数的和,并不清楚,但可以确定是整数,参数列表可以定义两个int类型的变量,由调用者调用方法时传递

    代码演示如下:

    public static void main(String[] args){
        // 调用方法 getSum,传递两个整数,这里传递的实际数据又称为实际参数
        // sum 接收方法计算后的结果作为返回值
        int sum = getSum(5,6);
        System.out.println(sum);
    }
    
    /*定义计算两个整数和的方法,返回值类型和计算结果都是 int
    参数:定义两个 int 类型参数。这两个参数称为形式参数*/
    public static int getSum(int a,int b){
        return a + b;
    }
    

    方法的调用

    方法在定义完毕后,方法不会自己运行,必须被调用才能执行 。【方法的调用有三种方式,直接调用赋值调用输出调用 ,三种调用方式自行搜索一下,这里只是简单了解。】我们可以在 主方法 main 中来调用我们自己定义好的方法。在主方法中,直接写要调用的方法名字就可以调用了【前提是你定义的方法 必须被 static 关键字修饰 才行】。

    public static void main(String[] args) {
    
        // 单独调用
        sum(10, 20);
        System.out.println("===========");
    
    
        // 打印调用
        System.out.println(sum(10, 20));    // 30
        System.out.println("===========");
    
    
        // 赋值调用
        int number = sum(15, 25);
        number += 100;
        System.out.println("变量的值:" + number);    // 140
    
    }
    
    public static int sum(int a, int b) {
        System.out.println("方法执行啦!");
        int result = a + b;
        return result;
    }
    

    方法的调用图解

    方法的重载

    方法重载:
    1、方法重载:指在同一个类中,允许存在一个以上的同名方法,只要它们的参数列表不同即可,与修饰符和返回值类型无关。 2、参数列表:个数不同,数据类型不同,顺序不同。 3、重载方法调用:JVM 通过方法的参数列表,调用不同的方法。

    方法重载 代码演示如下:

    public static void main(String[] args) {
    
        // 普通方法
        print(3, 3);
    
        // 方法重载:方法名字相同,形式参数的类型不同或者形式参数的个数不同
        // 重载: 方法名相同,参数列表不同,与返回值类型无关
        // 重载的分类: 1、参数个数不同 2、参数类型不同 3、参数顺序不同
        double sum1 = add(10, 20.1);
        System.out.println(sum1);
    
        int sum2 = add(10, 20, 30);
        System.out.println(sum2);
    
        double sum3 = add(12.3, 13);
        System.out.println(sum3);
    
    }
    
    
    /**
     * 在控制台输出矩形星形
     * 1、明确返回值类型,经分析没有具体的返回值类型,那么返回值类型就是 void
     * 2、明确参数列表 int a, int b
     */
    public static void print(int a, int b) {
        for (int i = 1; i <= a; i++) {                //行数
            for (int j = 1; j <= b; j++) {            //列数
                System.out.print("*");
            }
            System.out.println();
        }
        // 如果返回值类型是 void, return 可以省略,即使省略系统也会默认给加上, 形式是 return;
        //return ;
    }
    
    
    /**
     * 求两个整数的和
     * 1、返回值类型 int
     * 2、参数列表 int a, int b
     */
    public static double add(int a, double b) {
        return a + b;
    }
    
    
    /**
     * 求三个整数的和
     * 1、返回值类型 int
     * 2、参数列表 int a,int b,int c
     */
    public static int add(int a, int b, int c) {
        return a + b + c;
    }
    
    
    /**
     * 求两个小数的和
     * 1、返回值类型 double
     * 2、参数列表 double a, double b
     */
    public static double add(double a, int b) {
        return a + b;
    }
    

    方法的注意事项

    方法的注意事项:
    1、方法必须定义在类中方法外 2、方法不能定义在另一个方法里面 3、返回值类型必须要和语句返回的类型相同,否则编译失败

    还有 更多的注意事项 写在代码的注释里面了,代码演示如下:

    /**
     * 使用方法的时候,有如下注意事项:
     * 1、方法应该定义在类当中,但是不能在方法当中再定义方法。不能嵌套。
     * 2、方法定义的前后顺序无所谓。
     * 3、方法定义之后不会执行,如果希望执行,一定要调用。三种调用方式:单独调用、打印调用、赋值调用。
     * 4、如果方法有返回值,那么必须写上“return 返回值;”,不能不写。
     * 5、return 后面的返回值数据,必须和方法的返回值类型,对应起来。
     * 6、对于一个 void 没有返回值的方法,不能写 return 后面的返回值,只能写 return 自己。
     * 7、对于 void 方法当中最后一行的 return 可以省略不写。
     * 8、一个方法当中可以有多个 return 语句,但是必须保证同时只有一个会被执行到,两个 return 不能连写。
     */
    class MethodNotice {
    
        public static int method1() {
            return 10;
        }
    
    
        public static void method2() {
    //        return 10; // 错误的写法!方法没有返回值,return后面就不能写返回值。
            return; // 没有返回值,只是结束方法的执行而已。
        }
    
    
        public static void method3() {
            System.out.println("AAA");
            System.out.println("BBB");
    //        return; // 最后一行的return可以省略不写。
        }
    
    
        public static int getMax(int a, int b) {
            /*int max;
            if (a > b) {
                max = a;
            } else {
                max = b;
            }
            return max;*/
    
            /*if (a > b) {
                return a;
            } else {
                return b;
            }*/
            
            return a > b ? a : b;
        }
    
    }
    

    数组知识

    数组的概述和初始化

    容器的概述

    现在需要统计某公司员工的工资情况,例如 计算平均工资、找最高工资 等。假设该公司有 50 名员工,那么首先需要声明 50 个变量来分别记住每位员工的工资,然后再进行操作,这样做会显得很麻烦,而且错误率也会很高。因此我们可以使用 容器 进行操作。将所有的数据全部存储到一个容器中,统一操作。容器 是将多个数据存储到一起,每个数据称为该容器的 元素 。生活中常见的容器:水杯,衣柜,教室 等等。

    数组的概念

    数组 就是存储 数据长度固定 的容器,保证了多个数据的数据类型一致。数组的其他介绍都在代码里了,代码演示如下:

    /**
     * 01-数组的概念:数组是一种容器,可以同时存放多个数据值。
     * 02-数组的特点:
     *      1、数组是一种引用数据类型
     *      2、数组当中的多个数据,类型必须统一
     *      3、数组的长度在程序运行期间不可改变
     * 03-数组的初始化:在内存当中创建一个数组,并且向其中赋予一些默认值。
     * 04-两种常见的初始化方式:1. 动态初始化(指定长度)  2. 静态初始化(指定内容)
     * 05-动态初始化数组的格式:数据类型[] 数组名称 = new 数据类型[数组长度];
     * 06-解析含义:
     *      1、左侧数据类型:也就是数组当中保存的数据,全都是统一的数据类型
     *      2、左侧的中括号:代表是一个数组
     *      3、左侧数组名称:给数组取一个名字
     *      4、右侧的 new:代表创建数组的动作
     *      5、右侧数据类型:必须和左边的数据类型保持一致
     *      6、右侧中括号的长度:也就是数组当中,到底可以保存多少个数据,是一个 int 类型的值
     */
    public static void main(String[] args) {
        
        // 创建一个 int 类型的数组,里面可以存放 300 个 int 数据。 格式:数据类型[] 数组名称 = new 数据类型[数组长度];
        int[] arrayA = new int[300];
    
        // 创建一个 double 类型的数组,能存放 10 个 double 类型的数据
        double[] arrayB = new double[10];
    
        // 创建一个 String 类型的数组,能存放 5 个字符串
        String[] arrayC = new String[5];
    
    }
    

    数组的初始化

    接下来介绍 数组的初始化和注意事项 ,都写在代码里了,请看代码:

    /**
     * 01-动态初始化(指定长度):在创建数组的时候,直接指定数组当中的数据元素个数。
     * 02-静态初始化(指定内容):在创建数组的时候,不直接指定数据个数多少,而是直接将具体的数据内容进行指定。
     * 03-静态初始化标准格式:数据类型[] 数组名称 = new 数据类型[] { 元素1, 元素2, ... };
     * 04-使用静态初始化数组的时候,格式还可以省略。省略格式:数据类型[] 数组名称 = { 元素1, 元素2, ... };
     * 05-注意事项:
     *      1、静态初始化没有直接指定长度,但是根据大括号里面的元素具体内容,也可以自动推算出来长度。
     *      2、静态初始化标准格式可以拆分成为两个步骤。
     *      3、动态初始化也可以拆分成为两个步骤。
     *      4、静态初始化一旦使用省略格式,就不能拆分成为两个步骤了。
     * 06-使用建议:如果不确定数组当中的具体内容,用动态初始化;否则,已经确定了具体的内容,用静态初始化。
     */
    public static void main(String[] args) {
    
        // 直接创建一个数组,里面装的全都是 int 数字,具体为:5、15、25
        int[] arrayA = new int[]{5, 15, 25, 40};
    
        // 创建一个数组,用来装字符串:"Hello"、"World"、"Java"
        String[] arrayB = new String[]{"Hello", "World", "Java"};
    
        // 省略格式的静态初始化
        int[] arrayC = {10, 20, 30};
    
        // 静态初始化的标准格式,可以拆分成为两个步骤
        int[] arrayD;
        arrayD = new int[]{11, 21, 31};
    
        // 动态初始化也可以拆分成为两个步骤
        int[] arrayE;
        arrayE = new int[5];
    
        // 静态初始化的省略格式,不能拆分成为两个步骤。
    //    int[] arrayD;
    //    arrayD = { 10, 20, 30 };
    
    }
    

    数组的访问

    数组索引: 每一个存储到数组的元素,都会自动的拥有一个 编号,从 0 开始 ,这个自动编号称为 数组索引(index) 。我们可以通过 数组的索引 访问到 数组中的元素访问格式: 数组名[索引] ,代码演示如下:

    /**
     * 01-直接打印数组名称,得到的是数组对应的内存地址哈希值。
     * 02-进制了解:二进制:01    十进制:0123456789    十六进制:0123456789abcdef
     * 03-访问数组元素的格式:数组名称[索引值]。索引值:就是一个 int 数字,代表数组当中元素的编号。
     * 04-【注意】索引值从 0 开始,一直到 “ 数组的长度 - 1 ”为 止。
     * 05-使用动态初始化数组的时候,其中的元素将会自动拥有一个默认值。规则如下:
     *      如果是整数类型,那么默认为 0;
     *      如果是浮点类型,那么默认为 0.0;
     *      如果是字符类型,那么默认为 '\u0000';
     *      如果是布尔类型,那么默认为 false;
     *      如果是引用类型,那么默认为 null。
     * 06-注意事项:静态初始化其实也有默认值的过程,只不过系统自动马上将默认值替换成为了大括号当中的具体数值。
     */
    public static void main(String[] args) {
    
        // 静态初始化的省略格式
        int[] array = {10, 20, 30};
        System.out.println(array);    // 内存地址值
    
        // 直接打印数组当中的元素
        System.out.println(array[0]); // 10
        System.out.println(array[1]); // 20
        System.out.println(array[2]); // 30
        System.out.println("=============");
    
        // 也可以将数组当中的某一个单个元素,赋值交给变量
        int num = array[1];
        System.out.println(num);      // 20
    
        // 动态初始化一个数组,使用动态初始化数组的时候,其中的元素将会自动拥有一个默认值,具体规则如顶部注释。
        int[] array2 = new int[3];
        System.out.println(array);    // 内存地址值
    
        System.out.println(array[0]); // 0
        System.out.println(array[1]); // 0
        System.out.println(array[2]); // 0
        System.out.println("=================");
    
        // 将数据 123 赋值交给数组 array 当中的 1 号元素
        array2[1] = 123;
        System.out.println(array[0]); // 0
        System.out.println(array[1]); // 123
        System.out.println(array[2]); // 0
    }
    

    数组常见的错误

    数组一般会出现 两个常见错误数组越界异常空指针异常 。具体代码如下:

    /**
     * 01-数组的索引编号从 0 开始,一直到 “数组的长度 - 1” 为止。
     * 02-如果访问数组元素的时候,索引编号并不存在,那么将发生:数组索引越界异常: ArrayIndexOutOfBoundsException
     * 03-原因及解决方法:原因:索引编号写错了。解决方法:修改成为存在的正确索引编号。
     * 04-所有的引用类型变量,都可以赋值为一个 null 值。但是代表其中什么都没有。
     * 05-数组必须进行 new 初始化才能使用其中的元素。
     * 06-如果只是赋值了一个 null,没有进行 new 创建,那么将会发生:空指针异常: NullPointerException
     * 07-原因及解决方法:原因:忘了 new 。解决方法:补上 new
     */
    public static void main(String[] args) {
    
        int[] array = {15, 25, 35};
        System.out.println(array[0]); // 15
        System.out.println(array[1]); // 25
        System.out.println(array[2]); // 35
    
        // 错误写法:并不存在 3 号元素,所以发生数组越界异常
        System.out.println(array[3]);
    
        // 给数组 arr 赋值为 null
        int[] arr = null;
        System.out.println(arr[0]);   // 报错:NullPointerException ,IDEA 会有提示
    
        char[] ch = new char[]{'a', 'b', 'c'};
        // 这里输出的不是字符数组 ch 的地址,而是abc,
        // 因为 PrintStream 有多个重载的 println 方法,其中一个就是 public void println(char[] x),直接打印字符数组
        System.out.println(ch);
        // 如果要输出字符数组的地址,使用 toString() 方法
        System.out.println(ch.toString());
    
    }
    

    数组的各种操作

    第一种操作: 获取数组的长度 。代码演示如下:

    public static void main(String[] args) {
    
        // 静态初始化一个数组
        int[] arr = {1, 2, 3, 4, 5, 6, 7};
    
        // 获取数组的长度
        int length = arr.length;
    
        // 输出查看结果
        System.out.println("数组的长度:" + length);
    
    }
    

    第二种操作: 数组的遍历输出 。代码演示如下:

    public static void main(String[] args) {
    
        // 静态初始化一个数组
        int[] arr = {1, 2, 3, 4, 5, 6, 7};
    
        // 第一种遍历方式: foreach
        for (int i : arr) {
            System.out.println(i);
        }
    
        // 第二种遍历方式 for
        for (int i = 0; i < arr.length; i++) {
            System.out.println("arr[" + i + "] = " + arr[i]);
        }
    
    }
    

    第三种操作: 数组的最值获取 。代码演示如下:

    public static void main(String[] args) {
    
        // 静态初始化一个数组
        int[] arr = {10, 2, 3, 40, 50, 6, 70};
    
        int max = arr[0];
        int min = arr[0];
    
        for (int i = 1; i < arr.length; i++) {
            // 获取最大值并保存于变量 max 中
            if (arr[i] > max) {
                max = arr[i];
            }
    
            // 获取最小值并保存于变量 min 中
            if (arr[i] < min) {
                min = arr[i];
            }
        }
    
        System.out.println("数组中最小值为:" + min);
        System.out.println("数组中最大值为:" + max);
    
    }
    

    第四种操作: 数组的反转 。代码演示如下:

    public static void main(String[] args) {
    
        // 静态初始化一个数组
        int[] arr = {1, 2, 3, 4, 5, 6, 7};
    
        // 数组的反转
        for (int left = 0, right = arr.length - 1; left < right; left++, right--) {
            int temp;
            temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
        }
    
        // 数组的遍历
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    
    }
    

    第五种操作: 数组作为方法的参数 。代码演示如下:

    public static void main(String[] args) {
    
        // 静态初始化一个数组
        int[] arr = {1, 2, 3, 4, 5, 6, 7};
    
        // 调用 getMax() 方法,获取数组最大值
        int max = getMax(arr);
    
        // 输出查看结果
        System.out.println("数组的最大值为:" + max);
    
    }
    
    // 使用数组作为方法的参数,获取数组的最大值
    public static int getMax(int[] arr) {
    
        int max = arr[0];
    
        for (int i = 0; i < arr.length; i++) {
            if (max < arr[i]) {
                max = arr[i];
            }
        }
    
        return max;
    
    }
    

    第六种操作: 数组作为返回值 。代码演示如下:

    public static void main(String[] args) {
    
        // 调用 getArray() 方法获得数组
        int[] arr = getArray(2, 3, 4);
    
        // 打印查看结果
        System.out.println(Arrays.toString(arr));
    
    }
    
    // 使用数组作为方法的返回值,从而得到一个数组
    public static int[] getArray(int a, int b, int c) {
        int[] arr = {a, b, c};
        return arr;
    }
    

    数组的原理内存图

    内存的概述

    内存 是计算机中的重要原件,临时存储区域作用运行程序 。我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存。Java 虚拟机 要运行程序,必须要对内存进行空间的分配和管理。

    Java中的内存划分

    为了提高运算效率 ,就对内存空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。具体区域如下图:

    | 区域名称 | 作用 | | :-: | ---- | | 寄存器 | 给 CPU 使用,和我们开发无关。 | | 本地方法栈 | JVM 在使用操作系统功能的时候使用,和我们开发无关。 | | 方法区 | 存储可以运行的 class 文件。 | | 堆内存 | 存储对象或者数组,new 来创建的,都存储在堆内存。 | | 方法栈 | 方法运行时使用的内存,比如 main 方法运行,进入方法栈中执行。 |

    Java内存图 一个数组的内存图 两个数组的内存图

    两个引用指向同一个数组 的时候,他们操作的其实是 堆内的同一块区域 。先看代码:

    public static void main(String[] args) {
    
        // 定义第一个数组
        int[] arr1 = new int[]{12, 13, 14};
        // 定义第二个数组
        int[] arr2 = arr1;
    
        // 两个数组的内存地址相同
        System.out.println(arr1);
        System.out.println(arr2);
    
        // 改变数组的第三个元素
        arr2[2] = 234;
        System.out.println(arr1[2]);
        System.out.println(arr2[2]);
    }
    

    两个引用指向同一数组的内存图

    二维数组

    概念和初始化

    二维数组 就是 存储一维数组(内存地址/引用)的数组 。内存参考图如下:

    二维数组的初始化 ,详见代码:

    public static void main(String[] args) {
    
        // 二维数组不是规则的矩阵
        int[] arrayA[] = {{1, 2}, {2, 3, 4}, {3, 4, 5, 6}};
        System.out.println(arrayA); // [[I@5e265ba4 两个[[表示是二维的,I表示数组是int型,@5e265ba4是内存地址
    
        // 声明一个二维数组 arrayB ,用于存储 3 个一维数组,每一个一维数据存多少个数组,不知道 ,null
        int[][] arrayB = new int[3][];
    
        // 给 arrayB 赋值
        arrayB[0] = new int[3];             // 3
        arrayB[1] = new int[]{1, 2, 3, 4};  // 4
        arrayB[2] = new int[2];             // 2
    
        // 打印查看结果
        System.out.println(arrayB[1]);      // [I@156643d4
        System.out.println(arrayB[1][1]);   // 2
    
        // 声明一个二维数组,同时创建出一维数组,每个一维数组的长度均相同
        // 存储三个一维数组,每个一维数组的长度为 4
        int[] arrayC[] = new int[3][4];
        System.out.println(arrayC);
    
    }
    

    二维数组的遍历

    二维数组的遍历如下:

    /**
     * @Author: guoshizhan
     * @Create: 2020/3/3 23:19
     * @Description: 二维数组的遍历
     */
    public class ArrayTest {
    
        public static void main(String[] args) {
    
            // 定义一个二维数组 arr
            int[] arr[] = {{1, 2}, {2, 3, 4}, {3, 4, 5, 6}};
    
            // (1)普通 for 循环遍历
            for (int i = 0; i < arr.length; i++) { // 0, 1, 2
                for (int j = 0; j < arr[i].length; j++) { // 每一个一维数组的长度
                    System.out.print(arr[i][j] + "\t");
                }
                System.out.println();
            }
    
            // (2)加强 for 循环遍历
            System.out.println("\n-------------------------");
            for (int[] i : arr) {
                for (int j : i) {
                    System.out.print(j + "\t");
                }
                System.out.println();
            }
    
    
            // (3)普通与加强 for 循环的混搭
            System.out.println("\n-------------------------");
            for (int[] ints : arr) { // 加强 for
                for (int i = 0; i < ints.length; i++) {
                    System.out.print(ints[i] + "\t");
                }
                System.out.println();
            }
    
            // (3)普通与加强for循环的混搭
            System.out.println("\n-------------------------");
            for (int i = 0; i < arr.length; i++) {
                for (int j : arr[i]) { // 加强 for
                    System.out.print(j + "\t");
                }
                System.out.println();
            }
    
        }
    
    }
    

    多维数组

    声明一个数组,引用存在于栈中,new 出来的对象 存在堆中。三维数组及多维数组 一般很少用到,有用到时自己查吧!下面是一个 三维数组的创建和遍历输出 。代码如下:

    /**
     * @Author: guoshizhan
     * @Create: 2020/3/3 23:36
     * @Description: 三维数组的遍历
     */
    public class ArrayTest {
    
        public static void main(String arg[]) {
    
            // 创建一个三维数组 arr ,arr 存放了 3 个二维数组:arr[0]、arr[1]、arr[2]
            int[][][] arr = new int[3][][];
    
            // arr[0] ,存放了 3 个一维数组
            arr[0] = new int[3][];
            // arr[0][0] ,存放了 2 个数值
            arr[0][0] = new int[2];
            arr[0][0][0] = 1111;
            arr[0][0][1] = 1112;
            // arr[0][1] ,存放了 2 个数值
            arr[0][1] = new int[2];
            arr[0][1][0] = 1121;
            arr[0][1][1] = 1122;
            // arr[0][2] ,存放了 3 个数值
            arr[0][2] = new int[3];
            arr[0][2][0] = 1131;
            arr[0][2][1] = 1132;
            arr[0][2][2] = 1133;
    
    
            // arr[1] ,存放了 3 个一维数组
            arr[1] = new int[3][];
            // arr[1][0] ,存放了 2 个数值
            arr[1][0] = new int[2];
            arr[1][0][0] = 1211;
            arr[1][0][1] = 1212;
            // arr[1][1] ,存放了 2 个数值
            arr[1][1] = new int[2];
            arr[1][1][0] = 1221;
            arr[1][1][1] = 1222;
            // arr[1][2] ,存放了 2 个数值
            arr[1][2] = new int[2];
            arr[1][2][0] = 1231;
            arr[1][2][1] = 1232;
    
    
            // arr[2] ,存放了 3 个一维数组
            arr[2] = new int[3][];
            // arr[2][0] ,存放了 2 个数值
            arr[2][0] = new int[2];
            arr[2][0][0] = 1311;
            arr[2][0][1] = 1312;
            // arr[2][1] ,存放了 2 个数值
            arr[2][1] = new int[2];
            arr[2][1][0] = 1321;
            arr[2][1][1] = 1322;
            // arr[2][2] ,存放了 2 个数值
            arr[2][2] = new int[2];
            arr[2][2][0] = 1331;
            arr[2][2][1] = 1332;
    
            // 使用增强 for 循环输出结果
            for (int[][] a2 : arr) {
                for (int[] a1 : a2) {
                    for (int a: a1) {
                        System.out.print(a + "\t");
                    }
                    System.out.println();
                }
                System.out.println();
            }
    
        }
    
    }
    

    类与面向对象

    面向对象思想概述

    面向对象概述

    Java 语言 是一种 面向对象 的程序设计语言,而面向对象思想是一种程序设计思想。我们在面向对象思想的指引下,使用 Java 语言去设计、开发计算机程序。这里的对象泛指现实中一切事物,每种事物都具备自己的属性和行为 。面向对象思想就是在计算机程序设计过程中,参照现实中事物,将事物的 属性特征、行为特征 抽象出来,描述成计算机事件的设计思想。它区别于 面向过程思想面向对象思想 强调的是通过调用对象的行为来实现功能,而不是自己一步一步的去操作实现。

    面向对象举例

    洗衣服:
    面向过程:把衣服脱下来 --> 找一个盆 --> 放点洗衣粉 --> 加点水 --> 浸泡10分钟 --> 揉一揉 --> 清洗衣服 --> 拧干 --> 晾起来 面向对象:把衣服脱下来 --> 打开全自动洗衣机 --> 扔衣服 --> 按开关 --> 晾起来
    面向过程和面向对象的区别:
    面向过程:强调步骤。 面向对象:强调对象,这里的对象就是洗衣机。

    面向对象特点

    面向对象思想 是一种更符合我们思考习惯的思想,它可以 将复杂的事情简单化 ,并将我们从执行者变成了指挥者。面向对象的语言中,包含了 三大基本特征:即 封装继承多态 。这三大特性以后详细讲。

    类和对象

    环顾周围,你会发现很多 对象 ,比如 桌子,椅子,同学,老师 等。桌椅属于办公用品,师生都是人类。那么什么是类呢?什么是对象呢?

    什么是类

    类: 是一组相关属性和行为的集合 。可以看成是一类事物的 模板 ,使用事物的 属性特征和行为特征 来描述该类事物。现实中,我们可以这样描述一类事物 (属性 + 行为)属性 就是该事物的状态信息行为 就是该事物能够做什么

    类的举例:
    举例:小猫。 属性:名字、体重、年龄、颜色。 行为:走、跑、叫。

    类的定义格式

    类的定义格式:
    定义类:就是定义类的成员,包括成员变量和成员方法。 成员变量:和以前定义变量几乎是一样的。只不过位置发生了改变。在类中,方法外。 成员方法:和以前定义方法几乎是一样的。只不过把static去掉,static的作用在面向对象后面课程中再详细讲解。

    类的定义格式 代码演示如下:

    public class Student{
        // 成员变量
        String name; // 姓名
        int age;     // 年龄
    
        // 定义成员方法 study()
        public void study(){
            System.out.println("好好学习,天天向上");
        }
        // 定义成员方法 eat()
        public void eat(){
            System.out.println("学习饿了要吃饭");
        }
    }
    

    事物与类的对比

    现实世界的一类事物:
    属性:事物的状态信息。 行为:事物能够做什么。
    Java 中用 class 描述事物也是如此:
    成员变量:对应事物的属性 成员方法:对应事物的行为

    什么是对象

    对象: 是一类事物的具体体现 。对象是类的一个实例(对象并不是找个女朋友),必然具备该类事物的 属性和行为 。现实中,一类事物的一个实例就是对象 :一只小猫。属性: tom、5kg、2years、yellow。行为: 溜墙根走、蹦跶的跑、喵喵叫。

    类与对象的关系

    类与对象的关系:
    类是对一类事物的描述,是抽象的。 对象是一类事物的实例,是具体的。 类是对象的模板,对象是类的实体。

    举个例子,手机模板抽象的 ,不能被人使用,这个叫做 。但是 通过模板做成的手机具体的 ,可以被使用,叫做 对象 ,也叫 实体 。参考图如下:

    对象的使用

    对象的使用格式

    第一步: 了解 创建对象格式 以及 对象访问类中成员格式 ,如下:

    # 创建对象格式
    类名 对象名 = new 类名();
    
    
    #对象访问类中成员格式
    
    # 访问成员变量
    对象名.成员变量;
    
    # 访问成员方法
    对象名.成员方法();
    

    第二步: 创建 Student 实体类 ,代码如下:

    public class Student {
    
        public int age;
        public String name;
    
        public void study() {
            System.out.println("好好学习,天天向上");
        }
    
        public void eat() {
            System.out.println("学习饿了要吃饭");
        }
    
    }
    

    第三步: 创建 Student 类的测试类 StudentTest ,用于创建 Student 类的 对象 并访问其 成员变量及成员方法 ,代码如下:

    public class StudentTest {
    
        public static void main(String[] args) {
        
            // 创建对象格式:类名 对象名 = new 类名();
            Student stu = new Student();
            System.out.println("stu:" + stu);
            System.out.println("‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐");
        
            // 直接输出成员变量值
            System.out.println("姓名:" + stu.name);   // null
            System.out.println("年龄:" + stu.age);    // 0
            System.out.println("‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐");
        
            // 给成员变量赋值
            stu.name = "赵丽颖";
            stu.age = 18;
        
            // 再次输出成员变量的值
            System.out.println("姓名:" + stu.name);   // 赵丽颖
            System.out.println("年龄:" + stu.age);    // 18
            System.out.println("‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐");
        
            // 调用成员方法
            stu.study();    // "好好学习,天天向上"
            stu.eat();      // "学习饿了要吃饭"
        
        }
    
    }
    

    成员变量的默认值

    数据类型默认值
    整数(byte,short,int,long)0
    浮点数(float,double)0.0
    字符(char)'\u0000'
    布尔(boolean)false
    数组,类,接口null

    类和对象的练习

    第一步: 定义一个 手机类 Phone ,代码如下:

    public class Phone {
    
        // 成员变量
        String brand;    // 品牌
        double price;    // 价格
        String color;    // 颜色
    
        // 成员方法
        public void call(String name) {
            System.out.println("给" + name + "打电话");
        }
    
        public void sendMessage() {
            System.out.println("群发短信");
        }
    
    }
    

    第二步: 定义一个 测试类 PhoneTest ,代码如下:

    public class PhoneTest {
    
        public static void main(String[] args) {
    
            // 根据 Phone 类,创建一个名为 one 的对象
            // 格式:类名称 对象名 = new 类名称();
            Phone one = new Phone();
            System.out.println(one.brand);    // null
            System.out.println(one.price);    // 0.0
            System.out.println(one.color);    // null
            System.out.println("=========");
    
            one.brand = "苹果";
            one.price = 8388.0;
            one.color = "黑色";
    
            System.out.println(one.brand);    // 苹果
            System.out.println(one.price);    // 8388.0
            System.out.println(one.color);    // 黑色
            System.out.println("=========");
    
            one.call("乔布斯");   // 给乔布斯打电话
            one.sendMessage();    // 群发短信
    
        }
    
    }
    

    对象内存图

    一个对象

    两个对象

    作为参数

    作为返回值

    成员变量与局部变量

    两者概念

    成员变量 分为 类变量(static修饰)实例变量(无static)类变量 可以直接使用类名调用,实例变量 需要 创建对象 才能使用。局部变量 是定义在方法里或定义在方法的参数位置 。它们的具体区别如下:

    两者区别

    在类中的位置不同:
    成员变量:类中,方法外 局部变量:方法中或者方法声明上(形式参数)
    作用范围不一样:
    成员变量:类中 局部变量:方法中
    初始化值的不同:
    成员变量:有默认值 局部变量:没有默认值,必须先定义,赋值,最后使用
    在内存中的位置不同:
    成员变量:堆内存 局部变量:栈内存
    生命周期不同:
    成员变量:随着对象的创建而存在,随着对象的消失而消失 局部变量:随着方法的调用而存在,随着方法的调用完毕而消失

    封装特性

    封装概述

    面向对象 编程语言是对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界无法直接操作和修改。封装 可以被认为是一个保护屏障,防止该类的代码和数据被其他类随意访问。 要访问该类的数据,必须通过指定的方式。适当的封装可以让代码更容易理解与维护,也加强了代码的安全性

    原则: 将属性隐藏起来,若需要访问某个属性,提供公共方法对其访问。 封装步骤: ① 使用 private 关键字 来修饰成员变量。② 对需要访问的成员变量,提供对应的 一对 getxxx 方法、 setxxx 方法

    private 关键字

    private 的含义:
    private 是一个权限修饰符,代表最小权限。 可以修饰成员变量和成员方法。 被 private 修饰后的成员变量和成员方法,只在本类中才能访问。

    使用 private 修饰成员变量 ,代码如下:

    public class Student{
    
        // private 的使用格式:private 数据类型 变量名;
        private String name;
        private int age;
    
    }
    

    提供 getxxx 方法/ setxxx 方法 ,可以访问成员变量,代码如下:

    class Student {
    
        private String name;
        private int age;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
    }
    

    this 关键字

    请看下面一段代码,看是否会出现问题。代码如下:

    public class Student{
    
        private String name;
        private int age;
    
        public void setName(String name){
            name = name;
        }
    
        public void setAge(int age){
            age = age;
        }
    
    }
    

    经过测试,我们发现了一个问题,成员变量赋值失败了 。也就是说,在修改了的形参变量名后,方法并没有给成员变量赋值!这是由于 形参变量名与成员变量名重名 ,导致成员变量名被隐藏,方法中的变量名,无法访问到成员变量,从而赋值失败。所以,我们只能使用 this 关键字,来解决这个重名问题。this 代表所在类的当前对象的引用(地址值) ,即对象自己的引用。***方法被哪一个对象调用,方法中的 this 就代表那个对象。即谁在调用,this 就代表谁。***代码演示如下:

    class Student {
    
        private String name;
        private int age;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        // this 使用格式:this.成员变量名;
        public int getAge() {
            return age;
        }
    
        // this 使用格式:this.成员变量名;
        public void setAge(int age) {
            this.age = age;
        }
    
    }
    

    构造方法

    当一个对象被创建时候,构造方法 用来 初始化该对象,给对象的成员变量赋初始值

    小提示:

    无论你与否自定义构造方法,所有的类都有构造方法 。因为 Java 会 自动提供了一个无参数构造方法 。一旦自己定义了构造方法,那么 Java 自动提供的默认无参数构造方法就会失效,除非自己再重新定义一个无参构造方法。

    构造方法在写法上,方法名与它所在的类名相同 。它没有返回值,所以不需要返回值类型,甚至不需要 void 。代码演示如下:

    /**
     * 构造方法的格式:
     * 修饰符 构造方法名(参数列表) {
     *     //方法体
     * }
     */
    class Student {
    
        private String name;
        private int age;
    
        public Student() {    // 无参构造
        }
    
        public Student(String name, int age) {    // 有参构造
            this.name = name;
            this.age = age;
        }
    
    }
    
    注意事项:
    1、如果你不提供构造方法,系统会给出无参数构造方法。 2、如果你提供了构造方法,系统将不再提供无参数构造方法。 3、构造方法是可以重载的,既可以定义参数,也可以不定义参数。

    标准代码 JavaBean

    JavaBean 是 Java 语言编写类的一种 标准规范 。符合 JavaBean 的类,要求 类必须是具体的和公共的,并且具有无参数的构造方法 ,还需要提供用来操作成员变量的 getxxx 和 setxxx 方法

    public class ClassName{
    
        // 成员变量
        // 构造方法
        // 无参构造方法【必须】
        // 有参构造方法【建议】
        // 成员方法
        // getXxx()
        // setXxx()
    
    }
    

    编写符合 JavaBean 规范的类,以学生类为例,标准代码如下:

    class Student {
    
        // 成员变量
        private String name;
        private int age;
    
        // 无参构造方法
        public Student() {
        }
    
        // 有参构造方法
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        // getxxx 和 setxxx 方法
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }
    

    到此为止,Java 基础(上篇) 就结束了,接下来相关的文章是 Java 基础(中篇)

    Java
    • 文章作者:GuoShiZhan
    • 创建时间:2021-08-16 11:20:59
    • 更新时间:2021-10-05 21:44:06
    • 版权声明:本文为博主原创文章,未经博主允许不得转载!
    请 在 评 论 区 留 言 哦 ~~~
    1024