JavaSE

JavaSE

基础语法

1、第一个Java程序”Hello,World!“

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

注意:

  • 类名和文件名必须保持一致。
  • 用到的所有符号必须是在英文输入法下输入的符号。

2、注释

  • 单行注释:// 注释内容

  • 多行注释:/* 注释内容 */

  • 文档注释:/** 注释内容,且可以携带参数(如:@Author) */

  • 注意:注释不会被执行,它只是为了方便读者阅读代码。

    public class Demo01 {
        public static void main(String[] args) {
            //我是单行注释
            String str1 = "字符串1";
            /*
            我是多行注释,可以进行换行
             */
            String str2 ="字符串2";
            /**
             * @Author 作者
             * @Description 我是多行注释,可以携带参数
             */
            String str3 = "字符串3";
            //有趣的代码注释
        }
    }
    

3、标识符

  • 关键字:关键字是Java系统自己定义的,我们只要直接使用即可。

  • 常见标识符:

    abstract assert boolean break byte
    case catch char class const
    continue default do double else
    enum extends final finally float
    for goto if implements import
    instanceof int interface long native
    new package private protected public
    return strictfp short static super
    switch synchronized this throw throws
    transient try void volatile while
    • Java所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符

    • 标识符的特性:

      • 所有的标识符必须以字母(A-Z或a-z)、美元符($)、下划线(_)开头。

      • 首字符之后可以是字母、美元符、下划线以及数字的任意组合。

      • 不能使用关键字作为变量名和方法名。

      • 标识符大小写敏感

        public class Demo02 {
            public static void main(String[] args) {
                //属于两个不同的变量
                int abc1=1;
                int Abc1=1;
                
                int $ab1=1;
                int _abc1=1;
        //      int 2as=1;
                int 变量1=1;//不建议使用中文和拼音
            }
        }
        
      • 可以使用中文命名,但是不建议使用,也不建议使用拼音。

4、数据类型

  • 强类型语言:要求变量的使用必须严格符合规范,所有变量必须先声明再使用。

  • 弱类型语言:

  • Java的数据类型分类

    • 基本数据类型(primitive type)

    • 引用数据类型(reference type)

      基本数据类型:

      1665101198105

      引用数据类型:

      1665101228945

      public class Demo03 {
          public static void main(String[] args) {
              //八大基本数据类型
      
              //整数类型--默认为:int
              //Integer int1 = 12;
              byte num1 = 127;
              short num2 = 32767;
              int num3 = 2100000000;
              long num4 = 1000000000000L;
      
              //浮点类型---小数---默认为:double
              float num5 = 21.0F;
              double num6 = 21.0;
      
              //字符类型
              char char1 = 'a';
              char char2 = '国';
      
              //布尔类型:true或false---默认为:false
              boolean ble1 = true;
          }
      }
      
  • 什么是字符?

    • 位(bit):是计算机 内部数据 存储的最小单位,11001100是一个八位二进制。
    • 字节(byte):是计算机 内部数据 处理的最小单位,习惯用B表示。
    • 1B = 8bit
    • 字符:是指计算机中使用的字母、数字、字和符号。
  • 数据类型扩展

    public class Demo04 {
        public static void main(String[] args) {
            //整数扩展: 进制 二进制0b 十进制 八进制0 十六进制0x
            int num1 = 10;
            int num2 = 010; //八进制 0-7
            int num3 = 0x10; //十六进制 0-9 A-F
            System.out.println(num1);
            System.out.println(num2);
            System.out.println(num3);
            System.out.println("==================");
            //浮点数扩展:银行业务?
            //BigDecimal    数学工具类
            //float 有限 离散   舍入误差:大约---不要使用浮点数进行比较
            //double
            float f = 0.1F;
            double d = 0.1;
            System.out.println(f==d);//false
            float f2 = 1222222222f;
            float f3 = f2+1;
            System.out.println(f2==f3);//true
            System.out.println("==================");
            //字符串扩展
            char c1 = 'a';
            char c2 = '中';
            System.out.println(c1);
            System.out.println((int)c2);
            //所有字符本质都是数字
            //编码 Unicode 表:a=97,A=65 2字节 0-65536 2^16
            char c3 = '\u0061';
            System.out.println(c3);
            //转义字符:\t,\n等
            System.out.println("hello\tworld");
            String str1 = new String("123");
            String str2 = new String("123");
            System.out.println(str1==str2);//false
            String str3 = "123";
            String str4 = "123";
            System.out.println(str3==str4);//true
            System.out.println("==================");
            //布尔值扩展
            boolean flag = true;
            if(flag){}//less if more
        }
    }
    
  • 数据类型转换

    • 由于Java是强类型语言,所以要进行有些运算的时候,需要用到类型转换。

      1665103265671

    • 运算中,不同类型的数据先转化为同一类型,然后进行运算。

    • 强制类型转换

    • 自动类型转换

      public class Demo05 {
          public static void main(String[] args) {
              int b1 = 128;
              byte b2 = (byte)b1;//内存溢出
              System.out.println(b2);
      
              //强制类型转换: (数据类型)变量名  高-->低
              double d2 = 129;
              int i2 = (int)d2;
              //自动类型转换:低--->高
              int i = 128;
              double d = i;
      
              /*
              注意类型:
              1、不能对布尔类型转换
              2、不能把对象转化为不相干的类型
              3、在把大容量转化为小容量时,强制转换
              4、转换的时候可能存在内存溢出,或者精度问题。
               */
              System.out.println("=============");
              System.out.println((int)123.2);//123
              System.out.println((int)-45.89F);//-45
      
          }
      }
      
    • 注意:

      public class Demo06 {
          public static void main(String[] args) {
              //操作比较大的数据时,注意溢出问题。
              //JDK7新特性,数字之间可以用下划线分割
              int money = 10_0000_0000;
              int years = 20;
              int total = money * years;//-1474836480,数据溢出
              long total2 = money * years;//默认是int,转换之前,就已经存在问题
      
              long total3 = money * (long)years;//先把一个数转换为long
              System.out.println(total);
              System.out.println(total2);
              System.out.println(total3);
              //float和long尽量使用(F或L)
          }
      }
      

5、变量

  • 变量:就是可以变化的量

    • Java是一种强类型语言,每一个变量必须声明其类型。

    • Java变量是程序中最基础的存储单元,其要素包括变量名、变量类型和作用域

      type varName [= value][{,varName [= value]}];
      //数据类型 变量名 = 值;可以用多个逗号隔开来声明多个同一类型的变量,但不推荐使用。
      
  • 注意:

    • 每个变量都必须声明类型,类型可以是基本数据类型,也可以值引用类型。
    • 变量名必须是合法的标识符。
    • 变量声明是一条语句,必须以分号结束。
  • 变量类型:

    • 类变量

    • 实例变量

    • 局部变量

      public class Demo07 {
          //类变量 static
          static int salary = 2500;
          //实例变量:从属于对象
          //存在默认值:0、0.0、除了基本数据类型其余都是:null
          String name;
          int age;
      
          static {
              //代码块
          }
          //main 方法
          public static void main(String[] args) {
              //局部变量,必须声明和初始化值
              //只在{}之间有用,其他地方用不了
              int i = 1;
              System.out.println(i);
      
              //使用实例变量
              Demo07 demo07 = new Demo07();
              System.out.println(demo07.name);
              System.out.println(demo07.age);
      
              //使用类变量
              System.out.println(salary);
          }
      
          //其他方法
          public void add() {
      
          }
      }
      
      
  • 常量:初始化后不能再改变的值,即不变的量;(在变量前加”final“关键字即可)。

  • 命名规则:

    • 所以变量、方法、类名:见名知意。
    • 类成员变量:首字母小写和驼峰原则:monthSalary。
    • 局部变量:首字母小写和驼峰原则。
    • 常量:首字母大写和驼峰原则:MAX_VALUE。
    • 类名:首字母大写和驼峰原则:GoodMan。
    • 方法名:首字母小写和驼峰原则:runRun()。

6、基本运算

  • Java语言支持如下运算符:

    • 算术运算符:+,-,*,/,%,++,--

    • 赋值运算符:=

    • 关系运算符:>,<,>=,<=,==,!=,instanceof

    • 逻辑运算符:&&,||

    • 位运算符:&,|,^,~,>>,<<,>>>

    • 三元运算符(条件运算符):? :

    • 扩展赋值运算符:+=,-=,*=,/=

      public class Demo01 {
          public static void main(String[] args) {
              //二元运算符
              int a = 10;
              int b = 20;
              int c = 25;
              int d = 25;
              System.out.println(a+b);
              System.out.println(a-b);
              System.out.println(a*b);
              System.out.println(a/(double)b);
              System.out.println(a%b);
      
              //注意类型转换:运算前默认都转为int类型,最后类型看,最大容量的类型。
              long a2 = 121212121212L;
              int b2 = 124;
              short c2 = 12;
              byte d2 = 12;
              System.out.println(a2+b2+c2+d2);//long
              System.out.println(b2+c2+d2);//int
              System.out.println(c2+d2);//int
      
              //关系运算符:返回结果:true或false
              int a3 = 10;
              int b3 = 20;
              System.out.println(a3>b3);
              System.out.println(a3<b3);
              System.out.println(a3==b3);
              System.out.println(a3!=b3);
      
              //自增和自减:++,--
              //前b = ++a,先运算a = a+1,再赋值给b
              //后b = a++,先赋值给b,再运算a = a+1
              int a4 = 1;
              int b4 = a4++;//a++  a = a+1
              System.out.println(a);
              int c4 = ++a4;
              System.out.println(b4);
              System.out.println(c4);
              
              //数学工具类---Math
              //2^3
              System.out.println(Math.pow(2,3));
          }
      }
      
  • 逻辑运算符

    • && 和 ||

      public class Demo02 {
          public static void main(String[] args) {
              //逻辑运算符
              //与(and) 或(or) 非(取反)
              boolean a = true;
              boolean b = false;
              System.out.println("a && b:"+(a&&b));//逻辑与,两个变量都为真,结果才为true
              System.out.println("a || b:"+(a||b));//逻辑或,两个变量只要有一个为真,结果才为true
              System.out.println("!(a && b):"+!(a&&b));//逻辑非,真取反为假,假取反为真
      
              //短路运算
              System.out.println("b && a:"+(b&&a));//若第一个变量为false,则直接返回false,后面不运行
              System.out.println("a || b:"+(a||b));//若第一个变量为true,则直接返回true,后面不运行
          }
      }
      
  • 位运算

    public class Demo03 {
        public static void main(String[] args) {
            /*
            A = 0011 1100
            B = 0000 1101
            A&B = 0000 1100  对应位置比较,若都为1,则为1,否则为0。
            A|B = 0011 1101  对应位置比较,若存在一个为1,则为1。
            A^B = 0011 0001  对应位置比较,若相同,则为0;若不相同,则为1。
            ~B = 1111 0010 对应位置取反
            2*8 = 16  2*2*2*2
            效率高
            左移:>>  *2
            右移:<<  /2
            0000 0000   0
            0000 0000   1
            0000 0010   2
            0000 0011   3
            0000 0100   4
            0000 1000   8
             */
            System.out.println(2<<3);
        }
    }
    
  • 扩展运算符

    public class Demo04 {
        public static void main(String[] args) {
            int a = 10;
            int b = 20;
            a+=b; //a = a+b
            a-=b; //a = a-b
            System.out.println(a);
            //字符串连接符:+
            System.out.println(""+a+b);//1020
            System.out.println(a+b+"");//30
        }
    }
    
  • 三元运算符

    public class Demo05 {
        public static void main(String[] args) {
            //x ? y : z
            //如果x==true,则结果为y,否则结果为z
            int score = 80;
            String type = score < 60 ? "不及格" : "及格";
            System.out.println(type);
        }
    }
    
  • 优先级:()最高

7、包机制

  • 包机制

    • 为了更好的组织类,Java提供了包机制,用于区别类名的命名空间。

    • 包语句的语法格式为:

      package pkg1[.pak2.pak3...];
      
    • 一般利用公司域名倒置作为报名:com.feibinstudy.blog.www

    • 为了能够使用使用某一个包的成员,我们需要在Java程序中明确导入该包。使用”import“语句。

      import package1[.package2.package3...].(classname|*);
      
  • 文档注释

    /**
     * @Description
     * @Author 28051
     * @Date 2022-10-07 11:06
     */
    public class Demo08 {
        String name;
    
        /**
         * 
         * @param name
         * @return
         * @throws Exception
         */
        public String test(String name) throws Exception{
            return name;
        }
    }
    
    • 常见参数值:

      @author 作者名
      @version 版本号
      @since 指明需要最早使用的jdk版本
      @param 参数名
      @return 返回值情况
      @throws 异常抛出情况
      
    • 生成文档:

      //doc命令行生成JavaDoc文档
      javadoc -encoding UTF-8 -charset UTF-8 Demo01.java
      //使用idea生成JavaDoc文档!
      

流程控制

1、用户交互Scanner

  • Scanner是一个Java5的新特性,用户可以通过该类来获取用户的输入。

  • 基本语法:

    Scanner sc = new Scanner(System.in);
    
  • 通过Scanner类的next()与nextLine()方法获取输入的字符串,在读取前我们一般需要使用hasNext()与hasNestLine()判断是否还有输入的数据。

    public class Demo01 {
        public static void main(String[] args) {
            //创建一个扫描对象,用于接收用户键盘数据
            Scanner scanner = new Scanner(System.in);
            System.out.println("使用next方法接收:");
    
    //        使用hasNext()方法判断用户是否输入数据---以空格键为结束符
            if(scanner.hasNext()){
                //用next()方法接收数据
                String str = scanner.next();
                System.out.println("输出的内容为:"+str);
            }
    
            System.out.println("使用nextLine()方法接收:");
    //        使用hasNextLine()方法判断用户是否输入数据---以回车键为结束符
            if(scanner.hasNextLine()){
                String str2 = scanner.nextLine();
                System.out.println("输出的结构:"+str2);
            }
            /*常用方法:
            	nextInt()
            	nextDouble()
            	nextChar()
            	等等
            */
        }
    }
    

2、顺序结构

  • Java的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行。
  • 顺序结构是最简单的算法结构:从上往下依次执行。
  • 顺序结构是任何一个算法都离不开的一种基本算法结构。

3、if选择结构

  • if选择结构

    public class Demo01 {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入内容:");
            String str = scanner.nextLine();
    
    //        单选择结构
            if (str.equals("Hello")) {
                System.out.println("输入的内容:Hello");
            }
            System.out.println("程序继续执行!");
    
    //        双选择结构
            if(str.equals("world")) {
                System.out.println("输入的内容是world");
            }else {
                System.out.println("输入的内容不是world");
            }
            
    //        多分支结构
            if(str.equals("xiaomi")) {
                System.out.println("小米");
            } 
            else if(str.equals("huawei")) {
                System.out.println("华为");
            }else {
                System.out.println("其他情况!");
            }
        }
    }
    
    • 成绩判断

      public class Demo02 {
          public static void main(String[] args) {
              //考试成绩大于60就是及格,小于60就不及格
              Scanner scanner = new Scanner(System.in);
              System.out.println("请输入您的成绩:");
              double score = scanner.nextDouble();
              if(score==100){
                  System.out.println("你非常棒!");
              }
              else if(score >= 60){
                  System.out.println("你还不错");
              }else{
                  System.out.println("请继续努力!");
              }
          }
      }
      

4、Switch多选择结构

  • 多分支选择结构switch---case格式

    switch(expression){
        case value:
            //语句
            break;//可选
        case value:
            //语句
            break;//可选
        default://可选
            //语句
    }
    
  • switch语句中的变量类型可以是:

    • byte,short,int或者char
    • 从java7开始,switch支持字符串(其实质还是数字类型比较,通过反编译可知。)
  • idea反编译

    • 将.class文件直接拷贝到项目文件中,再打开即可。

      package com.feibinstudy.struct;
      
      import java.util.Scanner;
      
      public class DocDemo {
          public DocDemo() {
          }
      
          public static void main(String[] args) {
              Scanner scanner = new Scanner(System.in);
              System.out.println("请输入数据:");
              String s = scanner.nextLine();
              byte var4 = -1;
              switch(s.hashCode()) {
              case 99162322:
                  if (s.equals("hello")) {
                      var4 = 0;
                  }
                  break;
              case 113318802:
                  if (s.equals("world")) {
                      var4 = 1;
                  }
              }
      
              switch(var4) {
              case 0:
                  System.out.println("输入的结果为hello");
                  break;
              case 1:
                  System.out.println("输入的结果为world");
                  break;
              default:
                  System.out.println("不知道你输入的是神马!");
              }
      
          }
      }
      
      

5、while循环结构

  • 基本结构

    • 基本结构

      while(布尔表达式){
          //喜欢内容
      }
      
    • 只要布尔表达式为true,循环就会一直执行下去。

    • 循环条件一直为true,则为死循环,正常情况下,应尽量避免死循环。

    • 计算1+2+3+...+100=?

      package com.feibinstudy.struct;
      
      /**
       * @Description
       * @Author 28051
       * @Date 2022-10-10 10:25
       */
      public class WhileDemo01 {
          public static void main(String[] args) {
              //输出1-100之和:
              int i = 0;
              int sum = 0;
              while(i<=100) {
                  sum += i;
                  i++;
              }
              System.out.println(sum);
          }
      }
      
  • do-while结构

    • do-while循环和while相似,但是,do-while至少执行一次。

    • 结构

      do{
          //循环体
      }while(布尔表达式);
      
    • while和do-while的区别

      • while先判断后执行。do-while则先执行再判断。
      • do-while总是保证循环体被至少执行一次。

6、for循环

  • for循环语句是支持迭代的一种通用结构,是最有效,最灵活的循环结构。

  • for循环的次数,再循环前就已经确定了。

    for(初始化;布尔表达式;更新){
        //代码语句
    }
    
  • 分别计算0到100之间的奇数和偶数的和

    package com.feibinstudy.struct;
    
    /**
     * @Description
     * @Author 28051
     * @Date 2022-10-10 10:34
     */
    public class EvenDemo {
        public static void main(String[] args) {
            //分别计算0到100的奇数和偶数之和
            int evenSum=0;
            int overSum=0;
            for (int i = 0; i <= 100; i++){
                if (i%2==0){
                    System.out.print("偶数:" + i + ",");
                    overSum += i;
                }
                else if(i == 0){
                    System.out.println(i + "非奇非偶");
                }
                else{
                    System.out.println("奇数:" + i + ",");
                    evenSum += i;
                }
            }
            System.out.println("0到100之间的偶数和:" + overSum);
            System.out.println("0到100之间的奇数和:" + evenSum);
        }
    }
    
  • 用while或for循环输出1-1000之间能被5整除的数,并且每行输出3个数

    package com.feibinstudy.struct;
    
    /**
     * @Description
     * @Author 28051
     * @Date 2022-10-10 10:41
     */
    public class FDemo {
        public static void main(String[] args) {
            //求出1-1000之间能被5整除的数,并且每行输出3个数
            int flag = 1;
            while(flag < 1001){
                if (flag % 5 == 0){
                    System.out.print(flag + "\t");
                }
                if (flag % (5*3) == 0){
                    System.out.println();
                }
                flag++;
            }
            System.out.println("\n=========for==========");
            for (int i = 1; i < 1001; i++){
                if (i % 5 == 0){
                    System.out.print(i + "\t");
                }
                if (i % (5*3) == 0){
                    System.out.println();
                }
            }
        }
    }
    
    
  • 打印九九乘法表

    package com.feibinstudy.struct;
    
    /**
     * @Description
     * @Author 28051
     * @Date 2022-10-10 10:48
     */
    public class MultiplicationTable {
        public static void main(String[] args) {
            //打印九九乘法表
            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();
            }
        }
    }
    
  • 增强for

    • Java5引入了一种主要用于数组和集合的增强型for循环。

    • 语法

      for(声明语句:表达式){
          //代码
      }
      
    • 声明语句:什么新的局部变量,该变量的类型应该和数组元素或集合元素的类型匹配。其作用域限定在循环语句块,其值与此数组元素或集合元素的值相当。

    • 表达式:是要进行访问的数组名或集合名,活着是返回值为数组的方法。

      package com.feibinstudy.struct;
      
      /**
       * @Description
       * @Author 28051
       * @Date 2022-10-10 10:56
       */
      public class SFor {
          public static void main(String[] args) {
              //增强for循环
              int[] arr = {1,2,3,3,4};
              for (int elem:
                   arr) {
                  System.out.println(elem);
              }
          }
      }
      

7、break和continue

  • break在任何循环语句的主体部分,均可以用break控制循环的流程。break用于强行退出循环,不执行循环中剩余语句。

  • continue语句用于在循环语句体中,用于终止当前本次循环过程,即跳过循环中尚未执行的语句,接着进行下一次是否执行循环的判断。

    package com.feibinstudy.struct;
    
    import java.sql.SQLOutput;
    
    /**
     * @Description
     * @Author 28051
     * @Date 2022-10-10 11:02
     */
    public class BreakAndContinueDemo {
        public static void main(String[] args) {
            //break和continue
            int flag = 0;
            while (flag < 10){
                flag++;
                if (flag == 4){//当flag等于4时退出while循环
                    break;
                }
                System.out.println("flag的值:" + flag);
            }
            System.out.println("=============");
            flag = 0;
            do{
                flag++;
                if (flag == 4){//终止本次循环,后面的语句不再执行
                    continue;
                }
                System.out.println("flag的值:" + flag);
    
            }while (flag < 10);
        }
    }
    

8、打印三角形及Debug

  • 打印三角形

    package com.feibinstudy.struct;
    
    /**
     * @Description
     * @Author 28051
     * @Date 2022-10-10 11:10
     */
    public class SDemo02 {
        public static void main(String[] args) {
            //打印三角形1
            for (int i = 0; i < 9; i++) {
                for (int j = 0; j <= i-1; j++) {
                    System.out.print("*");
                }
                System.out.println();
            }
            //打印三角形2
            for (int i = 0; i <= 5; i++) {
                for (int j = 5; j >=i; j--) {
                    System.out.print(" ");
                }
                for (int j = 0; j <= i ; j++) {
                    System.out.print("*");
                }
                for (int j = 0; j < i; j++) {
                    System.out.print("*");
                }
                System.out.println();
            }
        }
    }
    

    三角形

  • Debug

    • 开启Debug

    开启Debug

    • 操作位置

      操作位置

Java方法

1、初识方法

  • 什么是方法

    • System.out.println(),System类的out对象的println()方法
    • Java方法是语句的集合。
      • 方法是解决一类问题的步骤的有序集合。
      • 方法包含于类或对象中。
      • 方法在程序中被创建,在其他地方被用。
  • 设计方法的原则

    • 方法的本意是功能块,就是实现某个功能的语句块的集合。在设计方法的时候,最好保持方法的原子性,就是一个方法只完成1个功能,利于后期维护。
  • 方法命名规则

  • 首字母小写+驼峰原则

  • 方法的定义

    • 方法包括一个方法头和一个方法体。

      修饰符 返回值类型 方法名(参数类型 参数名){
          //方法体
          return 返回值;
      }
      
    • 修饰符:修饰符,这是可选的,告诉编译器如何调用方法。定义了该方法的访问类型。

    • 返回值类型:方法可能会返回值。returnValueType是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType是关键字void。

    • 方法名:是方法的实际名称。方法名和参数表共同构成方法签名。

    • 参数类型:方法参数的类型。当方法被调用时,传递值给参数。这个值被称为实参或变量。

    • 方法体:定义该方法具体的功能。

      package com.feibinstudy.method;
      
      /**
       * @Description
       * @Author 28051
       * @Date 2022-10-10 17:44
       */
      public class Demo01 {
          public static void main(String[] args) {
      
              //方法调用--有返回值
              int maxValue = max(20,30);
              
              //方法调用--无返回值
              printHelloMethod();
          }
          //比较大小
          public static int max(int num1,int num2){
              if (num1 == num2){
                  System.out.println("num1==num2");
                  return 0;//return 除了可以方法值外,还用于结束方法
              }
              if(num1 > num2){
                  return num1;
              }else{
                  return num2;
              }
          }
          //输出Hello,method
          public static void printHelloMethod(){
              System.out.println("Hello,method");
          }
          
      }
      
    • 方法调用

      • Java支持两种调用方法,根据方法是否返回值来选择。

      • 当方法返回一个值时,方法调用通常被当做一个值。例如:

        int larger = max(30, 40);
        
      • 如果方法返回值是void,方法调用一定是一条语句。

        System.out.println("Hello,method!");
        

2、方法重载

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

  • 方法的重载规则:

    • 方法名必须完全相同。
    • 参数列表不同:参数个数不同或参数类型不同或类型顺序不同。
    • 与参数的返回值无关。
  • 实现理论

    • 方法名相同时,编译器会根据调用方法的参数个数、参数类型等逐个匹配,选择匹配对象方法进行执行。若无匹配对象,则会报错。

      package com.feibinstudy.method;
      
      /**
       * @Description
       * @Author 28051
       * @Date 2022-10-10 17:58
       */
      public class Demo02 {
          public static void main(String[] args) {
              //方法重载
          }
          //比较两个整数的大小
          public static int max(int num1, int num2){
              if (num1 == num2) {
                  System.out.println("num1 == num2");
                  return 0;
              }
              if(num1 > num2){
                  return num1;
              }else {
                  return num2;
              }
          }
          //比较两个浮点数的大小
          public static double max(double num1, double num2){
              if (num1 == num2) {
                  System.out.println("num1 == num2");
                  return 0;
              }
              if(num1 > num2){
                  return num1;
              }else {
                  return num2;
              }
          }
          //比较三个浮点数的大小
          public static double max(double num1, double num2, double num3){
              //....
              return 0;
          }
      }
      
    • 命令行传参

      1665396186226

3、可变的参数

  • JDK1.5开始,Java支持传递同类型的可变参数给一个方法。

  • 在方法声明中,在指定参数类型后加一个省略号(...)。

  • 一个方法中只能指定一个可变参数,且它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。

    package com.feibinstudy.method;
    
    /**
     * @Description
     * @Author 28051
     * @Date 2022-10-10 18:10
     */
    public class MoreElemMenthod {
        public static void main(String[] args) {
    
            //调用方法
            method(12,33.3,434.3);
        }
        //可变参数方法
        public static void method(int num1,double... nums) {
            for (int i = 0; i < nums.length; i++) {
                System.out.println("可变参数方法");
            }
        }
    }
    

4、递归

  • 递归:A方法调用A方法,即方法调用它本身。

  • 递归结构包括两个部分

    • 递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
    • 递归体:什么时候需要调用自身方法。
  • 阶乘计算

    package com.feibinstudy.method;
    
    /**
     * @Description
     * @Author 28051
     * @Date 2022-10-10 18:15
     */
    public class Factorial {
        public static void main(String[] args) {
    
            //调用方法计算5的阶乘
            System.out.println(sFactorial(5));
        }
        //一个计算阶乘的方法
        public static int sFactorial(int num){
            if (num == 1 || num == 0){
                return 1;
            }
            return num * sFactorial(num-1);
        }
    }
    

Java数组

1、数组概述

  • 数组定义
    • 数组是相同数据类型的数据的有序集合。
    • 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。
    • 每一数据叫做数组的元素。且可以通过下表访问到每一个数据(或元素)。

2、数组声明

  • 首先必须声明数组变量,才能在程序中使用数组。

  • 声明方法:

    dataType[] arrayName;
    int[] arr;
    
    datatype arrayName[];
    int arr[];
    
  • 使用new关键字创建数组

    dataType[] arrayName = new dataType[arraySize];
    int[] arr = new int[5];
    

3、数组使用

  • 数组的使用

    • 数组通过下标进行访问

      arrays[index]
      //定义
      int[] arrs = new int[12];
      //访问
      arrs[3];
      
  • 获取数组的长度

    arrs.length;
    
  • 三种初始化方法

    • 静态初始化

      int[] arrs = {1234};
      System.out.println(arrs[1]);
      
    • 动态初始化

      int[] arrs = new int[3];
      System.out.println(arrs[1]);
      
    • java.lang.ArrayIndexOutOfBoundsException----数组越界异常

      int[] arrs = new int[3];
      System.out.println(arrs[3]);//报java.lang.ArraysIndexOutOfBoundsException异常。
      
  • 内存分布

    1665454409679

  • 基本使用

    • For-Each循环

      class public ArraysDemo01{
          public static void main(String[] args){
              int[] arrs = {1,2,3,4,5,6};
              for(int i = 0; i < arrs.length; i++){
                  System.out.println(arrs[i]);
              }
              //采用for-each循环遍历数组元素
              for(int elem:
                 arrs){
                  //输出数组arrs中的每个元素
                  System.out.println(elem);
              }
          }
      }
      
    • 数组作为方法参数

      class public ArraysDemo02{
         public static void main(String[] args){
             int[] arrs = new int[5];
             arrs[0] = 1;
             //调用method01方法,并将arrs作为它的实参
             method01(arrs);
         }
         public static int method01(int[] arrs){
             System.out.println("=====将数组作为方法的参数=====");
             for(int elem:
                arrs){
                 System.out.println(elem);
             }
         }
      }
      
    • 数组作为返回值

      class public ArraysDemo03{
          public static void main(String[] args){
             int[] arrs = new int[5];
             arrs[0] = 1;
             //调用method02方法,并将arrs作为它的实参
             int[] arrs2 = method02(arrs);
          }
          //数组作为方法的返回值
          public static int[] method02(int[] arrs){
              System.out.println("数组作为方法的返回值");
              return arrs;
          }
      }
      
  • 数组的其他操作

    class public ArraysDemo{
        public static void main(String[] args){
            int[] arrays = {1,2,3,4,5};
            //调用遍历数组元素的方法
            printArray(arrays);
            //调用翻反转数组的方法
            int[] reverseArrays = reverse(arrays);
            printArray(reverseArrays);
        }
        //打印数组元素
        public static void printArray(int[] arrays){
            for(int elem:
               arrays){
                System.out.println(elem + " ")
            }
        }
       //反转数组
        public static int[] reverse(int[] arrays){
            int result = new int[arrays.length];
            //反转操作
            for(int i = 0,j=result.length-1; i < arrays.length; i++,j--){
                result[j] = arrays[i];
            }
            return result;
        }
    }
    

4、多维数组

  • 多维数组可以看作是数组的数组,比如二维数组就是一个特殊的一维数组,只是他的元素也是一个一维数组而已。

  • 二维数组定义

    int[][] arrs = new int[4][3];//4行3列二维数组
    int[][] arrs2 = new int[4][];//4行列数不确定的二维数组
    int[][] arrs3 ={{1,2,3},{4,5,6},{7,8,9}};
    
  • 二维数组的使用

    int[][] arrs = {{1,2,3},{4,5,6},{7,8,9}};
    //访问二维数组的元素
    System.out.println(arrs[1][1]);//arrs[1][1]--第二行第二列的元素
    /*
    	arrs ----表示arrs[0][0]
    	arrs[0]----表示第一行元素
    	arrs[1]----表示第二行元素
    */
    //遍历二维数组
    for(int i = 0; i < arrs.length; i++){
        for(int j = 0; j <arrs[i].length; i++){
            System.out.println(arrs[i][j]);
        }
    }
    

5、Arrays类

  • 数组的根据类java.util.Arrays

  • Arrays类提供了一系列的操作方法来操作数组。

  • Arrays类中的方法都市static关键字修饰的,在使用的时候可以直接使用类名进行调用,而不需要使用Arrays对象来调用。

  • 常用方法

    • 打印数组元素:toString()方法

    • 给数组赋值:fill方法

    • 对数组排序:sort方法

    • 比较数组:通过equals方法比较数组中元素的值是否相等。

    • 查找数组元素:通过binarySearch()方法能对已经排好序的数组进行二分查找操作。

      class public ArraysMethodDemo{
          public static void main(String[] args){
              int[] arrs = {1,2,3,4,4,5,5,2,3};
              //打印数组元素
              System.out.println(printArrays(arrs));
              System.out.println(Arrays.toString(arrs));
          }
          //打印数组元素的方法[1,2,3,4]
          public static String printArrays(int[] arrs){
              if(a == null){
                  return "b=null";
              }
              int iMax = arrs.length - 1;
              if(iMax == -1){
                  return "[]";
              }
              String result = null;
              for(int i = 0; i < arrs.length; i++){
                  if(i==0){
                      result = "[";
                  }
                  if(i==arrs.length-1){
                      result += a[i] + "]";
                  }else{
                      result += a[i] + ",";
                  }
              }
              return result;
          }
      }
      
  • 必须会使用java API文档

6、稀疏数组

Java中常用基础类

1、Number 和Math类

  • Number类

    • 一般地,当需要使用数字的时候,我们通常使用内置数据类型,如:byte、int、long、double 等。

      int a = 5000;
      float b = 13.65f;
      byte c = 0x4a;
      
    • 在实际开发过程中,我们经常会遇到需要使用对象,而不是内置数据类型的情形。为了解决这个问题,Java 语言为每一个内置数据类型提供了对应的包装类。

    • 所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类 Number 的子类。

      包装类 基本数据类型
      Boolean boolean
      Byte byte
      Short short
      Integer int
      Long long
      Character char
      Float float
      Double double

1665818726160

  • 装箱

    • 这种由编译器特别支持的包装称为装箱,所以当内置数据类型被当作对象使用的时候,编译器会把内置类型装箱为包装类。相似的,编译器也可以把一个对象拆箱为内置类型。Number 类属于 java.lang 包。

      public class Test{
       
         public static void main(String[] args){
            Integer x = 5;
            x =  x + 10;
            System.out.println(x); 
         }
      }
      
    • Java提供自动装箱过程。上面当 x 被赋为整型值时,由于x是一个对象,所以编译器要对x进行装箱。然后,为了使x能进行加运算,所以要对x进行拆箱。

  • Math类

    • Java 的 Math 包含了用于执行基本数学运算的属性和方法,如初等指数、对数、平方根和三角函数。

    • Math 的方法都被定义为 static 形式,通过 Math 类可以在主函数中直接调用。

      public class Test {  
          public static void main (String []args)  
          {  
              System.out.println("90 度的正弦值:" + Math.sin(Math.PI/2));  
              System.out.println("0度的余弦值:" + Math.cos(0));  
              System.out.println("60度的正切值:" + Math.tan(Math.PI/3));  
              System.out.println("1的反正切值: " + Math.atan(1));  
              System.out.println("π/2的角度值:" + Math.toDegrees(Math.PI/2));  
              System.out.println(Math.PI);  
          }  
      }
      
  • Number和Math类常用方法

    • 序号 方法与描述
      1 xxxValue()将 Number 对象转换为xxx数据类型的值并返回。
      2 compareTo()将number对象与参数比较。
      3 equals()判断number对象是否与参数相等。
      4 valueOf()返回一个 Number 对象指定的内置数据类型
      5 toString()以字符串形式返回值。
      6 parseInt() 将字符串解析为int类型。
      7 abs()返回参数的绝对值。
      8 ceil()返回大于等于( >= )给定参数的的最小整数,类型为双精度浮点型。
      9 floor()返回小于等于(<=)给定参数的最大整数 。
      10 rint()返回与参数最接近的整数。返回类型为double。
      11 round()它表示四舍五入,算法为 Math.floor(x+0.5),即将原来的数字加上 0.5 后再向下取整,所以,Math.round(11.5) 的结果为12,Math.round(-11.5) 的结果为-11。
      16 pow()返回第一个参数的第二个参数次方。
      17 sqrt()求参数的算术平方根。
      25 toDegrees()将参数转化为角度。
      26 toRadians()将角度转换为弧度。
      27 random() 返回一个随机数。

2、Character类

  • Character 类用于对单个字符进行操作。

  • Character 类在对象中包装一个基本类型 char 的值。

  • 在实际开发过程中,我们经常会遇到需要使用对象,而不是内置数据类型的情况。为了解决这个问题,Java语言为内置数据类型char提供了包装类Character类。

  • Character类提供了一系列方法来操纵字符。

  • 在某些情况下,Java编译器会自动创建一个Character对象。例如,将一个char类型的参数传递给需要一个Character类型参数的方法时,那么编译器会自动地将char类型参数转换为Character对象。
    这种特征称为装箱,反过来称为拆箱。

  • 转义字符

    • 前面有反斜杠(\)的字符代表转义字符,它对编译器来说是有特殊含义的。

      常见转义字符

      转义序列 描述
      \t 在文中该处插入一个tab键
      \b 在文中该处插入一个后退键
      \n 在文中该处换行
      \r 在文中该处插入回车
      \f 在文中该处插入换页符
      ' 在文中该处插入单引号
      " 在文中该处插入双引号
      \ 在文中该处插入反斜杠
      public class Test {
       
         public static void main(String[] args) {
            System.out.println("访问\"Java教程!\"");
         }
      }
      //结果
      // 访问"Java教程!"
      
  • Character类常用方法

    序号 方法与描述
    1 isLetter()是否是一个字母
    2 isDigit()是否是一个数字字符
    3 isWhitespace()是否是一个空白字符
    4 isUpperCase()是否是大写字母
    5 isLowerCase()是否是小写字母
    6 toUpperCase()指定字母的大写形式
    7 toLowerCase()指定字母的小写形式
    8 toString()返回字符的字符串形式,字符串的长度仅为1

3、String类

  • 字符串广泛应用 在 Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串。

  • 创建字符串

    String str = "Runoob";
    
    
    String str2=new String("Runoob");
    
  • String 创建的字符串存储在公共池中,而 new 创建的字符串对象在堆上:

    String s1 = "Runoob";              // String 直接创建
    String s2 = "Runoob";              // String 直接创建
    String s3 = s1;                    // 相同引用
    String s4 = new String("Runoob");   // String 对象创建
    String s5 = new String("Runoob");   // String 对象创建
    

    1665820458333

  • String 类有 11 种构造方法,这些方法提供不同的参数来初始化字符串。

    public class StringDemo{
        public static void main(String[] args){
            char[] helloArray = {'r', 'u', 'n', 'o', 'o', 'b'};
            String helloString = new String(helloArray);
            System.out.println( helloString );
        }
    }
    
  • 字符串长度

    • 用于获取有关对象的信息的方法称为访问器方法。

    • String 类的一个访问器方法是 length() 方法,它返回字符串对象包含的字符数。

      public class StringDemo{
          public static void main(String[] args){
              String site = "www.feibinstudy";
              int len = site.length();
              System.out.println(len);//15
          }
      }
      
  • 链接字符串

    • String 类提供了连接两个字符串的方法:

      string1.concat(string2);
      

      返回 string2 连接 string1 的新字符串。也可以对字符串常量使用 concat() 方法。

    • 常用的是使用'+'操作符来连接字符串,如:

      "Hello" + "runoob" + "!";//Hello, runoob!
      
  • 创建格式化字符串

    • String 类使用静态方法 format() 返回一个String 对象,能用来创建可复用的格式化字符串。

      System.out.printf("浮点型变量的值为 " +
                        "%f, 整型变量的值为 " +
                        " %d, 字符串变量的值为 " +
                        "is %s", floatVar, intVar, stringVar);
      
      String fs;
      fs = String.format("浮点型变量的值为 " +
                         "%f, 整型变量的值为 " +
                         " %d, 字符串变量的值为 " +
                         " %s", floatVar, intVar, stringVar);
      
  • String常用方法

    SN(序号) 方法描述
    1 char charAt(int index)返回指定索引处的 char 值。
    2 int compareTo(Object o)把这个字符串和另一个对象比较。
    3 int compareTo(String anotherString)按字典顺序比较两个字符串。
    4 int compareToIgnoreCase(String str)按字典顺序比较两个字符串,不考虑大小写。
    5 String concat(String str)将指定字符串连接到此字符串的结尾。
    6 boolean contentEquals(StringBuffer sb)当且仅当字符串与指定的StringBuffer有相同顺序的字符时候返回真。
    7 static String copyValueOf(char[] data)返回指定数组中表示该字符序列的 String。
    8 static String copyValueOf(char[] data, int offset, int count)返回指定数组中表示该字符序列的 String。
    9 boolean endsWith(String suffix)测试此字符串是否以指定的后缀结束。
    10 boolean equals(Object anObject)将此字符串与指定的对象比较。
    11 boolean equalsIgnoreCase(String anotherString)将此 String 与另一个 String 比较,不考虑大小写。
    12 byte[] getBytes()使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
    13 byte[] getBytes(String charsetName)使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
    14 void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)将字符从此字符串复制到目标字符数组。
    15 int hashCode()返回此字符串的哈希码。
    16 int indexOf(int ch)返回指定字符在此字符串中第一次出现处的索引。
    17 int indexOf(int ch, int fromIndex)返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索。
    18 int indexOf(String str)返回指定子字符串在此字符串中第一次出现处的索引。
    19 int indexOf(String str, int fromIndex)返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。
    21 int lastIndexOf(int ch)返回指定字符在此字符串中最后一次出现处的索引。
    22 int lastIndexOf(int ch, int fromIndex)返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索。
    23 int lastIndexOf(String str)返回指定子字符串在此字符串中最右边出现处的索引。
    24 int lastIndexOf(String str, int fromIndex)返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。
    25 int length()返回此字符串的长度。
    29 String replace(char oldChar, char newChar)返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。
    30 String replaceAll(String regex, String replacement)使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
    31 String replaceFirst(String regex, String replacement)使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。
    32 String[] split(String regex)根据给定正则表达式的匹配拆分此字符串。
    33 String[] split(String regex, int limit)根据匹配给定的正则表达式来拆分此字符串。
    34 boolean startsWith(String prefix)测试此字符串是否以指定的前缀开始。
    36 CharSequence subSequence(int beginIndex, int endIndex)返回一个新的字符序列,它是此序列的一个子序列。
    37 String substring(int beginIndex)返回一个新的字符串,它是此字符串的一个子字符串。
    38 String substring(int beginIndex, int endIndex)返回一个新字符串,它是此字符串的一个子字符串。
    39 char[] toCharArray()将此字符串转换为一个新的字符数组。
    40 String toLowerCase()使用默认语言环境的规则将此 String 中的所有字符都转换为小写。
    42 String toString()返回此对象本身(它已经是一个字符串!)。
    43 String toUpperCase()使用默认语言环境的规则将此 String 中的所有字符都转换为大写。
    45 String trim()返回字符串的副本,忽略前导空白和尾部空白。
    47 contains(CharSequence chars)判断是否包含指定的字符系列。
    48 isEmpty()判断字符串是否为空。

4、StringBuffer和StringBuilder类

  • StringBuffer类

    • 和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。

    • 在使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,所以如果需要对字符串进行修改推荐使用 StringBuffer。

    • 在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。

    • 常用方法

      序号 方法描述
      1 public StringBuffer append(String s)将指定的字符串追加到此字符序列。
      2 public StringBuffer reverse()将此字符序列用其反转形式取代。
      3 public delete(int start, int end) 移除此序列的子字符串中的字符。
      4 public insert(int offset, int i)int 参数的字符串表示形式插入此序列中。
      5 insert(int offset, String str)**将 str 参数的字符串插入此序列中。
      6 replace(int start, int end, String str)使用给定 String 中的字符替换此序列的子字符串中的字符。
      7 String toString()返回此序列中数据的字符串表示形式。
  • StringBuilder类

    • StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。

    • 由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。

      public class RunoobTest{
          public static void main(String[] args){
              StringBuilder sb = new StringBuilder(10);
              sb.append("Runoob..");
              System.out.println(sb);  
              sb.append("!");
              System.out.println(sb); 
              sb.insert(8, "Java");
              System.out.println(sb); 
              sb.delete(5,8);
              System.out.println(sb);  
          }
      }
      /*结果
      	Runoob..
      	Runoob..!
      	Runoob..Java!
      	RunooJava!
      */
      

      1665822143543

    1665821948483

5、Java 日期时间

  • Date()类

    • java.util 包提供了 Date 类来封装当前的日期和时间。
      Date 类提供两个构造函数来实例化 Date 对象。

    • 第一个构造函数使用当前日期和时间来初始化对象。

      Date();
      
    • 第二个构造函数接收一个参数,该参数是从 1970 年 1 月 1 日起的毫秒数。

      Date(long millisec);
      
    • 常用方法

      序号 方法和描述
      1 boolean after(Date date) 若当调用此方法的Date对象在指定日期之后返回true,否则返回false。
      2 boolean before(Date date) 若当调用此方法的Date对象在指定日期之前返回true,否则返回false。
      3 Object clone( ) 返回此对象的副本。
      4 int compareTo(Date date) 比较当调用此方法的Date对象和指定日期。两者相等时候返回0。调用对象在指定日期之前则返回负数。调用对象在指定日期之后则返回正数。
      5 int compareTo(Object obj) 若obj是Date类型则操作等同于compareTo(Date) 。否则它抛出ClassCastException。
      6 boolean equals(Object date) 当调用此方法的Date对象和指定日期相等时候返回true,否则返回false。
      7 long getTime( ) 返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
      8 int hashCode( ) 返回此对象的哈希码值。
      9 void setTime(long time) 用自1970年1月1日00:00:00 GMT以后time毫秒数设置时间和日期。
      10 String toString( ) 把此 Date 对象转换为以下形式的 String: dow mon dd hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)。
  • 获取当前日期时间

    import java.util.Date;
    
    public class DateDemo{
        public static void main(String[] args){
            //初始化 Date 对象
            Date date = new Date();
            //使用 toString() 函数显示日期时间
            System.out.println(date.toString());
        }
    }
    
  • 日期比较

    • 使用 getTime() 方法获取两个日期(自1970年1月1日经历的毫秒数值),然后比较这两个值。
    • 使用方法 before(),after() 和 equals()。例如,一个月的12号比18号早,则 new Date(99, 2, 12).before(new Date (99, 2, 18)) 返回true。
    • 使用 compareTo() 方法,它是由 Comparable 接口定义的,Date 类实现了这个接口。
  • 使用 SimpleDateFormat 格式化日期

    • SimpleDateFormat 是一个以语言环境敏感的方式来格式化和分析日期的类。SimpleDateFormat 允许你选择任何用户自定义日期时间格式来运行。

      import  java.util.*;
      import java.text.*;
      
      public class DateDemo{
          public static void main(String[] args){
              Date dNow = new Date();
              SimpleDateFormart ft = new SimpleDateFormart("yyyy-MM-dd hh:mm:ss");
              System.out.println("当前时间为: " + ft.format(dNow));
          }
      }
      
  • 使用printf格式化日期。

    import java.util.Date;
     
    public class DateDemo {
     
      public static void main(String[] args) {
         // 初始化 Date 对象
         Date date = new Date();
     
         //c的使用  
        System.out.printf("全部日期和时间信息:%tc%n",date);          
        //f的使用  
        System.out.printf("年-月-日格式:%tF%n",date);  
        //d的使用  
        System.out.printf("月/日/年格式:%tD%n",date);  
        //r的使用  
        System.out.printf("HH:MM:SS PM格式(12时制):%tr%n",date);  
        //t的使用  
        System.out.printf("HH:MM:SS格式(24时制):%tT%n",date);  
        //R的使用  
        System.out.printf("HH:MM格式(24时制):%tR",date);  
      }
    }
    

6、Java正则表达式

  • Java 正则表达式

    • 正则表达式定义了字符串的模式。

    • 正则表达式可以用来搜索、编辑或处理文本。

    • 正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。

    • java.util.regex 包主要包括以下三个类:

      • pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。

      • Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。

      • PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。

        import java.util.regex.*;
         
        class RegexExample1{
           public static void main(String[] args){
              String content = "I am noob " +
                "from runoob.com.";
         
              String pattern = ".*runoob.*";
         
              boolean isMatch = Pattern.matches(pattern, content);
              System.out.println("字符串中是否包含了 'runoob' 子字符串? " + isMatch);
           }
        }
        //字符串中是否包含了 'runoob' 子字符串? true 
        
      • 相关学习

7、Java Stream、File、IO

  • Java 流(Stream)、文件(File)和 IO

    • Java.io 包几乎包含了所有操作输入、输出需要的类。所有这些流类代表了输入源和输出目标。
    • Java.io 包中的流支持很多种格式,比如:基本类型、对象、本地化字符集等等。
    • 一个流可以理解为一个数据的序列。输入流表示从一个源读取数据,输出流表示向一个目标写数据。
    • Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。
  • 读取控制台输入

    • Java 的控制台输入由 System.in 完成。

    • 为了获得一个绑定到控制台的字符流,你可以把 System.in 包装在一个 BufferedReader 对象中来创建一个字符流。

    • 创建 BufferedReader 的基本语法:

      BufferedReader br = new BufferedReader(new 
                            InputStreamReader(System.in));
      
    • 使用 read() 方法从控制台读取一个字符,或者用 readLine() 方法读取一个字符串。

    • read() 方法,它从输入流读取一个字符并把该字符作为整数值返回。 当流结束的时候返回 -1。该方法抛出 IOException。

    • 用 read() 方法从控制台不断读取字符直到用户输入 q。

      //使用 BufferReader 在控制台读取字符
      
      import java.io.*;
      
      public class BRRead{
          public static void main(String[] args) throws IOException{
              char c;
              //使用 System.in 创建 BufferReader;
              BufferReader br new BufferReader(new InputStreamReader(System.in));
              System.out.println("输入字符,按下‘q’键退出。");
              //读取字符
              do{
                  c = (char) br.read();
                  System.out.println(c);
              }while(c != 'q');
          }
      }
      
  • 控制台输出

    import java.io.*;
     
    //演示 System.out.write().
    public class WriteDemo {
        public static void main(String[] args) {
            int b;
            b = 'A';
            System.out.write(b);
            System.out.write('\n');
        }
    }
    
    
  • 读写文件

    • 一个流被定义为一个数据序列。输入流用于从源读取数据,输出流用于向目标写数据。
    • 1665824738894
  • FileInputStream

    • 该流用于从文件读取数据,它的对象可以用关键字 new 来创建。

    • 有多种构造方法可用来创建对象。

    • 可以使用字符串类型的文件名来创建一个输入流对象来读取文件:

      InputStream f = new FileInputStream("c:/java/hello");
      
    • 使用一个文件对象来创建一个输入流对象来读取文件。我们首先得使用 File() 方法来创建一个文件对象:

      File f = new File("c:/java/hello");
      InputStream in = new FileInputStream(f);
      
    • 创建了InputStream对象,就可以使用下面的方法来读取流或者进行其他的流操作。

      序号 方法及描述
      1 public void close() throws IOException{} 关闭此文件输入流并释放与此流有关的所有系统资源。抛出IOException异常。
      2 protected void finalize()throws IOException {} 这个方法清除与该文件的连接。确保在不再引用文件输入流时调用其 close 方法。抛出IOException异常。
      3 public int read(int r)throws IOException{} 这个方法从 InputStream 对象读取指定字节的数据。返回为整数值。返回下一字节数据,如果已经到结尾则返回-1。
      4 public int read(byte[] r) throws IOException{} 这个方法从输入流读取r.length长度的字节。返回读取的字节数。如果是文件结尾则返回-1。
      5 public int available() throws IOException{} 返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取的字节数。返回一个整数值。
  • FileOutputStream

    • 该类用来创建一个文件并向文件中写数据。

    • 如果该流在打开文件进行输出前,目标文件不存在,那么该流会创建该文件。

    • 有两个构造方法可以用来创建 FileOutputStream 对象。

    • 使用字符串类型的文件名来创建一个输出流对象:

      OutputStream f = new FileOutputStream("c:/java/hello");
      
    • 使用一个文件对象来创建一个输出流来写文件。我们首先得使用File()方法来创建一个文件对象:

      File f = new File("C:/java/hello");
      OutputStream fOut = new FileOutputStream(f);
      
    • 创建OutputStream 对象完成后,就可以使用下面的方法来写入流或者进行其他的流操作。

      序号 方法及描述
      1 public void close() throws IOException{} 关闭此文件输入流并释放与此流有关的所有系统资源。抛出IOException异常。
      2 protected void finalize()throws IOException {} 这个方法清除与该文件的连接。确保在不再引用文件输入流时调用其 close 方法。抛出IOException异常。
      3 public void write(int w)throws IOException{} 这个方法把指定的字节写到输出流中。
      4 public void write(byte[] w) 把指定数组中w.length长度的字节写到OutputStream中。
      import java.io.*;
      
      public class FileStreamTest {
          public static void main(String[] args){
              try{
                  byte[] bWrite = {11,21,3,40,5};
                  OutputStream os = new FileOutputStream("test.txt");
                  for(int x = 0; x < bWrite.length; x++){
                      //将bWrite里面的数据写入test.txt文件
                      os.write(bWrite[x]);
                  }
                  os.close();
                  
                  InputStream is = new FileInoutStream("test.txt");
                  //获取数据流中有多少个字节可以读取
                  int size = is.available();
                  for(int i = 0; i < size; i++){
                      //从test.txt读取数据
                      System.out.println((char)is.read() + " ");
                  }
                  is.close();
              } catch (IOException e){
                  System.out.println("Exception!");
              }
          }
      }
      

      以上代码由于是二进制写入,可能存在乱码,你可以使用以下代码实例来解决乱码问题:

      import java.io.*;
      
      public class fileStreamTest2 {
          public static void main(String[] args) throws IOException {
       
              File f = new File("a.txt");
              FileOutputStream fop = new FileOutputStream(f);
              // 构建FileOutputStream对象,文件不存在会自动新建
       
              OutputStreamWriter writer = new OutputStreamWriter(fop, "UTF-8");
              // 构建OutputStreamWriter对象,参数可以指定编码,默认为操作系统默认编码,windows上是gbk
       
              writer.append("中文输入");
              // 写入到缓冲区
       
              writer.append("\r\n");
              // 换行
       
              writer.append("English");
              // 刷新缓存冲,写入到文件,如果下面已经没有写入的内容了,直接close也会写入
       
              writer.close();
              // 关闭写入流,同时会把缓冲区内容写入文件,所以上面的注释掉
       
              fop.close();
              // 关闭输出流,释放系统资源
       
              FileInputStream fip = new FileInputStream(f);
              // 构建FileInputStream对象
       
              InputStreamReader reader = new InputStreamReader(fip, "UTF-8");
              // 构建InputStreamReader对象,编码与写入相同
       
              StringBuffer sb = new StringBuffer();
              while (reader.ready()) {
                  sb.append((char) reader.read());
                  // 转成char加到StringBuffer对象中
              }
              System.out.println(sb.toString());
              reader.close();
              // 关闭读取流
       
              fip.close();
              // 关闭输入流,释放系统资源
       
          }
      }
      
  • Java中的目录

    • 创建目录:File类中有两个方法可以用来创建文件夹:

      • mkdir( )方法创建一个文件夹,成功则返回true,失败则返回false。失败表明File对象指定的路径已经存在,或者由于整个路径还不存在,该文件夹不能被创建。

      • mkdirs()方法创建一个文件夹和它的所有父文件夹。

        import java.io.File;
        
        public class CreaderDir{
            public static void main(String[] args){
                String dirname = "/tmp/user/java/bi";
                File d = new File(dirname);
                //创建目录
                d.mkdirs();
            }
        }
        
    • 读取目录:一个目录其实就是一个 File 对象,它包含其他文件和文件夹。

      • 如果创建一个 File 对象并且它是一个目录,那么调用 isDirectory() 方法会返回 true。

      • 可以通过调用该对象上的 list() 方法,来提取它包含的文件和文件夹的列表。

        import java.io.File;
         
        public class DirList {
            public static void main(String args[]) {
                String dirname = "/tmp";
                File f1 = new File(dirname);
                if (f1.isDirectory()) {
                    System.out.println("目录 " + dirname);
                    String s[] = f1.list();
                    for (int i = 0; i < s.length; i++) {
                        File f = new File(dirname + "/" + s[i]);
                        if (f.isDirectory()) {
                            System.out.println(s[i] + " 是一个目录");
                        } else {
                            System.out.println(s[i] + " 是一个文件");
                        }
                    }
                } else {
                    System.out.println(dirname + " 不是一个目录");
                }
            }
        }
        
    • 删除目录或文件:使用 java.io.File.delete() 方法。

      import java.io.File;
       
      public class DeleteFileDemo {
          public static void main(String[] args) {
              // 这里修改为自己的测试目录
              File folder = new File("/tmp/java/");
              deleteFolder(folder);
          }
       
          // 删除文件及目录
          public static void deleteFolder(File folder) {
              File[] files = folder.listFiles();
              if (files != null) {
                  for (File f : files) {
                      if (f.isDirectory()) {
                          deleteFolder(f);
                      } else {
                          f.delete();
                      }
                  }
              }
              folder.delete();
          }
      }
      

面向对象编程

1、初识面向对象

  • 面向过程
    • 以过程为中心的编程思想。分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用即可。
  • 面向对象
    • 面向对象,就是将相关的数据和方法组织为一个整体看待,从更高层次的角度进行系统建模。

2、方法回顾和加深

  • 方法的定义

    • 修饰符
      • 对方法的作用范围进行规范。
    • 返回类型
    • break和return的区别
      • break跳出switch语句和结束循环,而return是结束方法。并且return的返回值必须和返回值类型相同。
    • 方法名
      • 即方法名的别名,必须见明知意。
    • 参数列表
      • 即形参,用于接收传递的实参。
    • 异常抛出

  • 方法的调用

    • 静态方法

      • 静态方法即用static修饰符进行修饰的方法。在调用另外一个类的静态方法是可以直接使用:类名.方法名();
    • 非静态方法

      • 非静态方法即没有用static修饰符进行修饰的方法。在调用时,必须通过实例化对象后,再对象名.方法名();调用。
    • 形参和实参

      • 形参是指方法小括号里面的参数列表
      • 实参是指调用方法时传递的参数。
    • 值传递和引用传递

      • 值传递相当于将实参的值拷贝一份给方法。
      • 引用传递的本质还是值传递。将形参指向实参的物理地址。
      public class Demo04{
          public static void main(String[] args){
              int a = 1;
              System.out.println(a);//1
              //值传递
              Demo04.change(a);//1
              //引用传递
              String str = "hello";
      		System.out.println(str);//hello
              Demo04.changeA(str)
              System.out.println(str);//change
          }
        
          public static void change(int a){
              a = 10;
          }
          public static String changeA(int a){
              a = "change";
              return a;
          }
      }
      
    • this关键字

      public class Demo01{
          public static void main(String[] args){
              new Demo01().say();
              Demo01.say2();
          }
          /*
          修饰符 返回值类型 方法名(参数列表){
          	//方法体
          	return 返回值;
          }
          */
          public String sayHello(){
              return "hello,world";
          }
          public int max(int a, int b){
              return a>b? a : b;
          }
          //异常抛出
          public void readFile(String file) throws IOException{
              //方法体
              return;
          }
          //非静态方法
          public void say(){
              System.out.println("你好");
          }
          //静态方法
          public static void say2(){
              System.out.println("你好2");
          }
          
      }
      

3、对象的创建分析

    • 类是对现实生活中一类具有共同特征的事物的抽象。
    • 类是一种用户定义的引用数据类型,也称类类型。每个类包含数据说明和一组操作数据或传递消息的函数。
    • 类其实类似于 byte、short、int(char)、long、float、double 等基本数据类型,不同的是它是一种复杂的数据类型。因为它的本质是数据类型,而不是数据,所以不存在于内存中,不能被直接操作,只有被实例化为对象时,才会变得可操作。
    • 类的内部封装了属性和方法,用于操作自身的成员。
  • 对象

    • 对象即一个具体的人或事物,如张三。
    • 一个对象有状态、行为和标识三种属性。
    • 构造
      • 一个类默认情况下存在一个无参构造器。
      • 在声明有参构造器后,如果要调用无参构造器,必须手动声明。
    //学生类
    public class Student{
        //构造器---主要用于属性的初始化操作
        //无参构造器
        public Student(){
            
        }
        //有参构造器
        public Student(String name){
            this.name;
        }
        
        //属性或字段---存在初始化值
        String name;
        int age;
        
        //方法
        public void study(){
            System.out.println(this.name + "在学习!");
        }
    }
    
    //测试类:一个项目应该只存在一main方法
    public class Application{
        public static void main(String[] args){
            //类的实例化,返回一个对象。
            //student01即一个类的具体实例。
            //new 后前本质是一个类的构造器
            Student student01 = new Student();
        }
    }
    

4、面向对象三大特性

  • 封装

    • 将数据和操作捆绑在一起,创造出一个新的类型的过程。或将接口与实现分离的过程。
  • 继承

    • 类之间的关系,在这种关系中,一个类共享了一个或多个其他类定义的结构和行为。继承描述了类之间的“是一种”关系。子类可以对基类的行为进行扩展、覆盖、重定义。

    • 对类的继承使用extends关键字实现。

    • 对接口的实现用implements关键字。

    • Java只允许单继承。

    • 重写

      • 即在子类中对父类方法的重写。
    • super

      • super调用父类的构造方法,必须在子类构造方法的第一行。
      • super必须只能出现在子类的方法或者构造方法中。
      • super和this不能同时调用构造方法。
      • this代表的对象是本身调用者。
      • super代表的是对父类对象的引用。
      //测试类
      public class Apolication{
          public static void main(Stringp[] args){
              Son son01 = new Son();
              son01.say();
              /*输出结构:
              	我是父类构造器!
              	我是子类的构造器!
              	我是子类!
              */
          }
      }
      
      //父亲类
      public class Person{
          public Person(){
              System.out.println("我是父类构造器!");
          }
          String name;
          int age;
          
          public void say(){
              System.out.println("我是父类!");
          }
      }
      
      //儿子类---子类继承父类所以非final的属性和方法,并且可以有自己特殊的属性和方法。	
      public class Son extends Person{
          //构造函数
          public Son(){
              //隐含super()
              super();//---调用父类的构造器,调用父类的构造器必须放在子类构造器中的第一行
              System.out.println("我是子类的构造器!");
          }
          String name;
          int age;
          
          public void say(){
              System.out.println("我是子类!");
          }
      }
      
  • 多态

    • 类型理论中的一个概念,一个名称可以表示很多不同类的对象,这些类和一个共同超类有关。因此,这个名称表示的任何对象可以以不同的方式响应一些共同的操作集合。

    • 多态存在的条件

      • 有继承关系
      • 子类重写父类方法
      • 父类引用指向子类对象
    • 多态是方法的多态,属性没有多态。

    • instanceof关键字,判断一个对象是什么类型。

      public class Application{
          public static void main(String[] args){
              System.out.println(Object instanceof Student);//true
          }
      }
      
    • static

      public class Student{
          private static int age;//静态变量
          private double score;//非静态变量
          /*
          	非静态方法可以调用静态方法和非静态方法
          	静态方法只能调用静态方法,不能调用非静态方法。
          */
          public void run(){
              go();
          }
          public static void go(){
              
          }
          
          //匿名代码块
          {
              //匿名代码块
          }
          //静态代码块
          static{
              //静态代码块
          }
          public static void main(String[] args){
              Student student1 new Student();
              System.out.println(student1.age);
              System.out.println(student1.score);
              
              //静态属性推荐使用类名调用
              System.out.println(Student.age);
              Student.go();
          }
      }
      
      public class Person{
          //匿名代码块--赋初始值
          {
              System.out.println("我是匿名代码块");
          }
          
          //静态代码块--静态代码块只执行一次
          static{
              System.out.println("我是静态代码块");
          }
          
          //构造方法
          public Person(){
              System.out.println("我是构造方法");
          }
          public static void main(String[] args){
              Person person = new Person();
              /*结果:
              		我是静态代码块
              		我是匿名代码块
              		我是构造方法
              */
              Person person2 = new Person();
              /*结果
              		我是匿名代码块
              		我是构造方法
              */
          }
      }
      

5、抽象类和接口

  • 抽象类

    • abstract修饰的类,就是抽象类。

    • 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。

    • 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。

    • 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。

    • 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。

    • 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。

    • 抽象方法

      • 如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。
      • Abstract 关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。
      • 抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。
      • 如果一个类包含抽象方法,那么该类必须是抽象类。
      • 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。
      • 继承抽象方法的子类必须重写该方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该抽象方法,否则,从最初的父类到最终的子类都不能用来实例化对象。
      public abstract class Employee{
          private String name;
          private String address;
          private int number;
          public Employee(String name, String address, int number){
              System.out.println("Constructing an Employee");
              this.name = name;
              this.address = address;
              this.number = number;
          }
          public double computePay(){
              System.out.println("Inside Employee computePay");
              return 0.0;
          }
          public void mailCheck()
         {
            System.out.println("Mailing a check to " + this.name
             + " " + this.address);
         }
         public String toString()
         {
            return name + " " + address + " " + number;
         }
         public String getName()
         {
            return name;
         }
         public String getAddress()
         {
            return address;
         }
         public void setAddress(String newAddress)
         {
            address = newAddress;
         }
         public int getNumber()
         {
           return number;
         }
          //Abstract method----抽象方法,只定义方法结构,抽象类的子类进行实现。
          public abstract void method();
      }
      
      //继承抽象类
      public class Salary extends Employee
      {
         private double salary; //Annual salary
         public Salary(String name, String address, int number, double
            salary)
         {
             super(name, address, number);
             setSalary(salary);
         }
         public void mailCheck()
         {
             System.out.println("Within mailCheck of Salary class ");
             System.out.println("Mailing check to " + getName()
             + " with salary " + salary);
         }
         public double getSalary()
         {
             return salary;
         }
         public void setSalary(double newSalary)
         {
             if(newSalary >= 0.0)
             {
                salary = newSalary;
             }
         }
         public double computePay()
         {
            System.out.println("Computing salary pay for " + getName());
            return salary/52;
         }
          public abstract void method(){
          	System.out.println("我是抽象类的抽象方法的具体实现");
          }
      }
      
  • 接口

    • 接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。

    • 接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。

    • 除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。

    • 接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

    • 接口没有构造方法。

    • 接口中所有的方法必须是抽象方法,Java 8 之后 接口中可以使用 default 关键字修饰的非抽象方法。

    • 接口不能包含成员变量,除了 static 和 final 变量。

    • 接口不是被类继承了,而是要被类实现。

    • 接口支持多继承。

    • 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。

    • 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。

    • 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。

      //声明接口
      [可见度] interface 接口名称 [extends 其他的接口名] {
              // 声明变量
              // 抽象方法
      }
      //eg:
      interface Animal {
         public void eat();
         public void travel();
      }
      
      //接口被实现
      public class MammalInt implements Animal{
       
         public void eat(){
            System.out.println("Mammal eats");
         }
       
         public void travel(){
            System.out.println("Mammal travels");
         } 
       
         public int noOfLegs(){
            return 0;
         }
       
         public static void main(String args[]){
            MammalInt m = new MammalInt();
            m.eat();
            m.travel();
         }
      }
      

6、Java 异常处理

  • Java 异常处理

    • 异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。
    • 异常分类
      • 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
      • 运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
      • 错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
  • Exception 类的层次

    • 所有的异常类是从 java.lang.Exception 类继承的子类。

    • Exception 类是 Throwable 类的子类。除了Exception类外,Throwable还有一个子类Error 。

    • Java 程序通常不捕获错误。错误一般发生在严重故障时,它们在Java程序处理的范畴之外。

    • Error 用来指示运行时环境发生的错误。

    • 异常类有两个主要的子类:IOException 类和 RuntimeException 类。

      1665826964392

  • Java 内置异常类

    • 非检查性异常

      异常 描述
      ArithmeticException 当出现异常的运算条件时,抛出此异常。例如,一个整数"除以零"时,抛出此类的一个实例。
      ArrayIndexOutOfBoundsException 用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则该索引为非法索引。
      ArrayStoreException 试图将错误类型的对象存储到一个对象数组时抛出的异常。
      ClassCastException 当试图将对象强制转换为不是实例的子类时,抛出该异常。
      IllegalArgumentException 抛出的异常表明向方法传递了一个不合法或不正确的参数。
      IllegalMonitorStateException 抛出的异常表明某一线程已经试图等待对象的监视器,或者试图通知其他正在等待对象的监视器而本身没有指定监视器的线程。
      IllegalStateException 在非法或不适当的时间调用方法时产生的信号。换句话说,即 Java 环境或 Java 应用程序没有处于请求操作所要求的适当状态下。
      IllegalThreadStateException 线程没有处于请求操作所要求的适当状态时抛出的异常。
      IndexOutOfBoundsException 指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。
      NegativeArraySizeException 如果应用程序试图创建大小为负的数组,则抛出该异常。
      NullPointerException 当应用程序试图在需要对象的地方使用 null 时,抛出该异常
      NumberFormatException 当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。
      SecurityException 由安全管理器抛出的异常,指示存在安全侵犯。
      StringIndexOutOfBoundsException 此异常由 String 方法抛出,指示索引或者为负,或者超出字符串的大小。
      UnsupportedOperationException 当不支持请求的操作时,抛出该异常。
    • 检查性异常

      异常 描述
      ClassNotFoundException 应用程序试图加载类时,找不到相应的类,抛出该异常。
      CloneNotSupportedException 当调用 Object 类中的 clone 方法克隆对象,但该对象的类无法实现 Cloneable 接口时,抛出该异常。
      IllegalAccessException 拒绝访问一个类的时候,抛出该异常。
      InstantiationException 当试图使用 Class 类中的 newInstance 方法创建一个类的实例,而指定的类对象因为是一个接口或是一个抽象类而无法实例化时,抛出该异常。
      InterruptedException 一个线程被另一个线程中断,抛出该异常。
      NoSuchFieldException 请求的变量不存在
      NoSuchMethodException 请求的方法不存在
  • 异常方法

    • Throwable 类的主要方法:

      序号 方法及说明
      1 public String getMessage() 返回关于发生的异常的详细信息。这个消息在Throwable 类的构造函数中初始化了。
      2 public Throwable getCause() 返回一个 Throwable 对象代表异常原因。
      3 public String toString() 返回此 Throwable 的简短描述。
      4 public void printStackTrace() 将此 Throwable 及其回溯打印到标准错误流。。
      5 public StackTraceElement [] getStackTrace() 返回一个包含堆栈层次的数组。下标为0的元素代表栈顶,最后一个元素代表方法调用堆栈的栈底。
      6 public Throwable fillInStackTrace() 用当前的调用栈层次填充Throwable 对象栈层次,添加到栈层次任何先前信息中。
  • 捕获异常

    • 使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。

    • try/catch代码块中的代码称为保护代码,使用 try/catch 的语法如下:

      try
      {
         // 程序代码
      }catch(ExceptionName e1)
      {
         //Catch 块
      }
      

      Catch 语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try 后面的 catch 块就会被检查。

      如果发生的异常包含在 catch 块中,异常会被传递到该 catch 块,这和传递一个参数到方法是一样。

      import java.io.*;
      public class ExcepTest{
       
         public static void main(String args[]){
            try{
               int a[] = new int[2];
               System.out.println("Access element three :" + a[3]);
            }catch(ArrayIndexOutOfBoundsException e){
               System.out.println("Exception thrown  :" + e);
            }
            System.out.println("Out of the block");
         }
      }
      
  • 多重捕获块

    • 一个 try 代码块后面跟随多个 catch 代码块的情况就叫多重捕获。

      try{
         // 程序代码
      }catch(异常类型1 异常的变量名1){
        // 程序代码
      }catch(异常类型2 异常的变量名2){
        // 程序代码
      }catch(异常类型3 异常的变量名3){
        // 程序代码
      }
      
      

      catch里面的异常类型从上往下必须是小范围到大范围。

  • throws/throw 关键字

    • 如果一个方法没有捕获到一个检查性异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。

    • 也可以使用 throw 关键字抛出一个异常,无论它是新实例化的还是刚捕获到的。

    • 一个方法可以声明抛出多个异常,多个异常之间用逗号隔开。

      import java.io.*;
      public class className
      {
        public void deposit(double amount) throws RemoteException,InsufficientFundsException
        {
          // Method implementation
          throw new RemoteException();
        }
        //Remainder of class definition
      }
      
  • finally 关键字

    • finally 关键字用来创建在 try 代码块后面执行的代码块。

    • 无论是否发生异常,finally 代码块中的代码总会被执行。

    • 在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。

      try{
        // 程序代码
      }catch(异常类型1 异常的变量名1){
        // 程序代码
      }catch(异常类型2 异常的变量名2){
        // 程序代码
      }finally{
        // 程序代码
      }
      
      public class ExcepTest{
        public static void main(String args[]){
          int a[] = new int[2];
          try{
             System.out.println("Access element three :" + a[3]);
          }catch(ArrayIndexOutOfBoundsException e){
             System.out.println("Exception thrown  :" + e);
          }
          finally{
             a[0] = 6;
             System.out.println("First element value: " +a[0]);
             System.out.println("The finally statement is executed");
          }
        }
      }
      
    • catch 不能独立于 try 存在。

    • 在 try/catch 后面添加 finally 块并非强制性要求的。

    • try 代码后不能既没 catch 块也没 finally 块。

    • try, catch, finally 块之间不能添加任何代码。

  • try-with-resources

    • JDK7 之后,Java 新增的 try-with-resource 语法糖来打开资源,并且可以在语句执行完毕后确保每个资源都被自动关闭 。

    • JDK7 之前所有被打开的系统资源,比如流、文件或者 Socket 连接等,都需要被开发者手动关闭,否则将会造成资源泄露。

      try (resource declaration) {
        // 使用的资源
      } catch (ExceptionType e1) {
        // 异常块
      }
      
      import java.io.*;
      
      public class RunoobTest {
      
          public static void main(String[] args) {
          String line;
              try(BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
                  while ((line = br.readLine()) != null) {
                      System.out.println("Line =>"+line);
                  }
              } catch (IOException e) {
                  System.out.println("IOException in try block =>" + e.getMessage());
              }
          }
      }
      

      不使用 try-with-resources 而改成 finally 来关闭资源,整体代码量多了很多,而且更复杂繁琐了:

      import java.io.*;
      
      class RunoobTest {
          public static void main(String[] args) {
              BufferedReader br = null;
              String line;
      
              try {
                  System.out.println("Entering try block");
                  br = new BufferedReader(new FileReader("test.txt"));
                  while ((line = br.readLine()) != null) {
                  System.out.println("Line =>"+line);
                  }
              } catch (IOException e) {
                  System.out.println("IOException in try block =>" + e.getMessage());
              } finally {
                  System.out.println("Entering finally block");
                  try {
                      if (br != null) {
                          br.close();
                      }
                  } catch (IOException e) {
                      System.out.println("IOException in finally block =>"+e.getMessage());
                  }
              }
          }
      }
      
  • try-with-resource 处理多个资源

    • try-with-resources 语句中可以声明多个资源,方法是使用分号 ; 分隔各个资源:使用 Scanner 对象从 testRead.txt 文件中读取一行并将其写入新的 testWrite.txt 文件中。

      import java.io.*;
      import java.util.*;
      class RunoobTest {
          public static void main(String[] args) throws IOException{
              try (Scanner scanner = new Scanner(new File("testRead.txt"));
                  PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
                  while (scanner.hasNext()) {
                      writer.print(scanner.nextLine());
                  }
              }
          }
      }
      
  • 声明自定义异常

    • 在 Java 中你可以自定义异常。编写自己的异常类时需要记住下面的几点。

      • 所有异常都必须是 Throwable 的子类。

      • 如果希望写一个检查性异常类,则需要继承 Exception 类。

      • 如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。

        import java.io.*;
         
        //自定义异常类,继承Exception类
        public class InsufficientFundsException extends Exception
        {
          //此处的amount用来储存当出现异常(取出钱多于余额时)所缺乏的钱
          private double amount;
          public InsufficientFundsException(double amount)
          {
            this.amount = amount;
          } 
          public double getAmount()
          {
            return amount;
          }
        }
        
        import java.io.*;
         
        //此类模拟银行账户
        public class CheckingAccount
        {
          //balance为余额,number为卡号
           private double balance;
           private int number;
           public CheckingAccount(int number)
           {
              this.number = number;
           }
          //方法:存钱
           public void deposit(double amount)
           {
              balance += amount;
           }
          //方法:取钱
           public void withdraw(double amount) throws
                                      InsufficientFundsException
           {
              if(amount <= balance)
              {
                 balance -= amount;
              }
              else
              {
                 double needs = amount - balance;
                 throw new InsufficientFundsException(needs);
              }
           }
          //方法:返回余额
           public double getBalance()
           {
              return balance;
           }
          //方法:返回卡号
           public int getNumber()
           {
              return number;
           }
        }
        
        public class BankDemo
        {
           public static void main(String [] args)
           {
              CheckingAccount c = new CheckingAccount(101);
              System.out.println("Depositing $500...");
              c.deposit(500.00);
              try
              {
                 System.out.println("\nWithdrawing $100...");
                 c.withdraw(100.00);
                 System.out.println("\nWithdrawing $600...");
                 c.withdraw(600.00);
              }catch(InsufficientFundsException e)
              {
                 System.out.println("Sorry, but you are short $"
                                          + e.getAmount());
                 e.printStackTrace();
              }
            }
        }
        
  • 通用异常

    • 在Java中定义了两种类型的异常和错误。
      • JVM(Java虚拟机) 异常:由 JVM 抛出的异常或错误。例如:NullPointerException 类,ArrayIndexOutOfBoundsException 类,ClassCastException 类。
      • 程序级异常:由程序或者API程序抛出的异常。例如 IllegalArgumentException 类,IllegalStateException 类。

7、继承

  • 继承的概念

    • 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
    • 例子:兔子和羊属于食草动物类,狮子和豹属于食肉动物类。
    • 所以继承需要符合的关系是:is-a,父类更通用,子类更具体。
  • 类的继承格式

    class 父类 {
    }
     
    class 子类 extends 父类 {
    }
    
    • 实例:开发动物类,其中动物分别为企鹅以及老鼠:企鹅:属性(姓名,id),方法(吃,睡,自我介绍),老鼠:属性(姓名,id),方法(吃,睡,自我介绍)

      //公共父类
      public class Animal{
          private String name;
          private int id;
          public Animal(String myName, int myid) { 
              name = myName; 
              id = myid;
          } 
          public void eat(){ 
              System.out.println(name+"正在吃"); 
          }
          public void sleep(){
              System.out.println(name+"正在睡");
          }
          public void introduction() { 
              System.out.println("大家好!我是"         + id + "号" + name + "."); 
          } 
      }
      
      //企鹅类
      public class Penguin extends Animal { 
          public Penguin(String myName, int myid) { 
              super(myName, myid); 
          } 
      }
      
      //老鼠类
      public class Mouse extends Animal { 
          public Mouse(String myName, int myid) { 
              super(myName, myid); 
          } 
      }
      
  • 继承的类型

    1665835835441

  • 继承的特性

    • 子类拥有父类非 private 的属性、方法。
    • 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
    • 子类可以用自己的方式实现父类的方法。
    • Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
    • 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
  • 继承关键字

    • 继承可以使用 extends 和 implements 这两个关键字来实现继承,而且所有的类都是继承于java.lang.Object,当一个类没有继承的两个关键字,则默认继承 Object(这个类在 java.lang 包中,所以不需要 import)祖先类。

    • 在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类。

      public class Animal { 
          private String name;   
          private int id; 
          public Animal(String myName, int myid) { 
              //初始化属性值
          } 
          public void eat() {  //吃东西方法的具体实现  } 
          public void sleep() { //睡觉方法的具体实现  } 
      } 
       
      public class Penguin  extends  Animal{ 
      }
      
    • 使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。

      public interface A {
          public void eat();
          public void sleep();
      }
       
      public interface B {
          public void show();
      }
       
      public class C implements A,B {
      }
      
  • super 和 this 关键字

    • super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。

    • this关键字:指向自己的引用。

      class Animal {
        void eat() {
          System.out.println("animal : eat");
        }
      }
       
      class Dog extends Animal {
        void eat() {
          System.out.println("dog : eat");
        }
        void eatTest() {
          this.eat();   // this 调用自己的方法
          super.eat();  // super 调用父类方法
        }
      }
       
      public class Test {
        public static void main(String[] args) {
          Animal a = new Animal();
          a.eat();
          Dog d = new Dog();
          d.eatTest();
        }
      }
      
  • final 关键字

    • final 可以用来修饰变量(包括类属性、对象属性、局部变量和形参)、方法(包括类方法和对象方法)和类。

    • 使用 final 关键字声明类,就是把类定义定义为最终类,不能被继承,或者用于修饰方法,该方法不能被子类重写:

      • 声明类

        final class 类名 {//类体}
        
      • 声明方法

        修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}
        
  • 构造器

    • 子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表。

    • 如果父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器。

      class SuperClass {
        private int n;
        SuperClass(){
          System.out.println("SuperClass()");
        }
        SuperClass(int n) {
          System.out.println("SuperClass(int n)");
          this.n = n;
        }
      }
      // SubClass 类继承
      class SubClass extends SuperClass{
        private int n;
        
        SubClass(){ // 自动调用父类的无参数构造器
          System.out.println("SubClass");
        }  
        
        public SubClass(int n){ 
          super(300);  // 调用父类中带有参数的构造器
          System.out.println("SubClass(int n):"+n);
          this.n = n;
        }
      }
      // SubClass2 类继承
      class SubClass2 extends SuperClass{
        private int n;
        
        SubClass2(){
          super(300);  // 调用父类中带有参数的构造器
          System.out.println("SubClass2");
        }  
        
        public SubClass2(int n){ // 自动调用父类的无参数构造器
          System.out.println("SubClass2(int n):"+n);
          this.n = n;
        }
      }
      public class TestSuperSub{
        public static void main (String args[]){
          System.out.println("------SubClass 类继承------");
          SubClass sc1 = new SubClass();
          SubClass sc2 = new SubClass(100); 
          System.out.println("------SubClass2 类继承------");
          SubClass2 sc3 = new SubClass2();
          SubClass2 sc4 = new SubClass2(200); 
        }
      }
      

8、重写(override)和重载(overload)

  • 重写

    • 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!

    • 重写的好处在于子类可以根据需要,定义特定于自己的行为。也就是说子类能够根据需要实现父类的方法。

    • 重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。例如:父类的一个方法申明了一个检查异常 IOException,但是在重写这个方法的时候不能抛出 Exception 异常,因为 Exception 是 IOException 的父类,抛出 IOException 异常或者 IOException 的子类异常。

    • 在面向对象原则里,重写意味着可以重写任何现有方法。实例如下:

      class Animal{
         public void move(){
            System.out.println("动物可以移动");
         }
      }
       
      class Dog extends Animal{
         public void move(){
            System.out.println("狗可以跑和走");
         }
      }
       
      public class TestDog{
         public static void main(String args[]){
            Animal a = new Animal(); // Animal 对象
            Animal b = new Dog(); // Dog 对象
       
            a.move();// 执行 Animal 类的方法
       
            b.move();//执行 Dog 类的方法
         }
      }
      

      在上面的例子中可以看到,尽管 b 属于 Animal 类型,但是它运行的是 Dog 类的 move方法。

      这是由于在编译阶段,只是检查参数的引用类型。

      然而在运行时,Java 虚拟机(JVM)指定对象的类型并且运行该对象的方法。

      因此在上面的例子中,之所以能编译成功,是因为 Animal 类中存在 move 方法,然而运行时,运行的是特定对象的方法。

  • 方法的重写规则

    • 参数列表与被重写方法的参数列表必须完全相同。
    • 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本可以不同)。
    • 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。
    • 父类的成员方法只能被它的子类重写。
    • 声明为 final 的方法不能被重写。
    • 声明为 static 的方法不能被重写,但是能够被再次声明。
    • 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。
    • 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。
    • 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
    • 构造方法不能被重写。
    • 如果不能继承一个类,则不能重写该类的方法。
  • super 关键字的使用

    • 当需要在子类中调用父类的被重写方法时,要使用 super 关键字。

      class Animal{
         public void move(){
            System.out.println("动物可以移动");
         }
      }
       
      class Dog extends Animal{
         public void move(){
            super.move(); // 应用super类的方法
            System.out.println("狗可以跑和走");
         }
      }
       
      public class TestDog{
         public static void main(String args[]){
       
            Animal b = new Dog(); // Dog 对象
            b.move(); //执行 Dog类的方法
       
         }
      }
      
  • 重载

    • 重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
    • 每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
    • 最常用的地方就是构造器的重载。
  • 重载规则

    • 被重载的方法必须改变参数列表(参数个数或类型不一样);

    • 被重载的方法可以改变返回类型;

    • 被重载的方法可以改变访问修饰符;

    • 被重载的方法可以声明新的或更广的检查异常;

    • 方法能够在同一个类中或者在一个子类中被重载。

    • 无法以返回值类型作为重载函数的区分标准。

      public class Overloading {
          public int test(){
              System.out.println("test1");
              return 1;
          }
       
          public void test(int a){
              System.out.println("test2");
          }   
       
          //以下两个参数类型顺序不同
          public String test(int a,String s){
              System.out.println("test3");
              return "returntest3";
          }   
       
          public String test(String s,int a){
              System.out.println("test4");
              return "returntest4";
          }   
       
          public static void main(String[] args){
              Overloading o = new Overloading();
              System.out.println(o.test());
              o.test(1);
              System.out.println(o.test(1,"test3"));
              System.out.println(o.test("test4",1));
          }
      }
      
  • 方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式。

9、多态

  • 概述

    • 多态是同一个行为具有多个不同表现形式或形态的能力。

    • 多态就是同一个接口,使用不同的实例而执行不同操作,如图所示:

      1665837825190

    • 多态性是对象多种表现形式的体现。

  • 多态存在的三个必要条件

    • 继承

    • 重写

    • 父类引用指向子类对象:Parent p = new Child();

      1665837947122

      class Shape {
          void draw() {}
      }
       
      class Circle extends Shape {
          void draw() {
              System.out.println("Circle.draw()");
          }
      }
       
      class Square extends Shape {
          void draw() {
              System.out.println("Square.draw()");
          }
      }
       
      class Triangle extends Shape {
          void draw() {
              System.out.println("Triangle.draw()");
          }
      }
      
    • 当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

    • 多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。

    • 以下是一个多态实例的演示,详细说明请看注释:

      public class Test {
          public static void main(String[] args) {
            show(new Cat());  // 以 Cat 对象调用 show 方法
            show(new Dog());  // 以 Dog 对象调用 show 方法
                      
            Animal a = new Cat();  // 向上转型  
            a.eat();               // 调用的是 Cat 的 eat
            Cat c = (Cat)a;        // 向下转型  
            c.work();        // 调用的是 Cat 的 work
        }  
                  
          public static void show(Animal a)  {
            a.eat();  
              // 类型判断
              if (a instanceof Cat)  {  // 猫做的事情 
                  Cat c = (Cat)a;  
                  c.work();  
              } else if (a instanceof Dog) { // 狗做的事情 
                  Dog c = (Dog)a;  
                  c.work();  
              }  
          }  
      }
       
      abstract class Animal {  
          abstract void eat();  
      }  
        
      class Cat extends Animal {  
          public void eat() {  
              System.out.println("吃鱼");  
          }  
          public void work() {  
              System.out.println("抓老鼠");  
          }  
      }  
        
      class Dog extends Animal {  
          public void eat() {  
              System.out.println("吃骨头");  
          }  
          public void work() {  
              System.out.println("看家");  
          }  
      }
      
  • 多态的实现方式

    • 重写
    • 接口
    • 抽象类和抽象方法

10、封装

  • 在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。

  • 实现Java封装的步骤

    • 修改属性的可见性来限制对属性的访问(一般限制为private),例如:

      public class Person {
          private String name;
          private int age;
      }
      
    • 对每个值属性提供对外的公共方法访问,也就是创建一对赋取值方法,用于对私有属性的访问,例如:

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

      public class EncapTest{
       
         private String name;
         private String idNum;
         private int age;
       
         public int getAge(){
            return age;
         }
       
         public String getName(){
            return name;
         }
       
         public String getIdNum(){
            return idNum;
         }
       
         public void setAge( int newAge){
            age = newAge;
         }
       
         public void setName(String newName){
            name = newName;
         }
       
         public void setIdNum( String newId){
            idNum = newId;
         }
      }
      
      public class RunEncap{
         public static void main(String args[]){
            EncapTest encap = new EncapTest();
            encap.setName("James");
            encap.setAge(20);
            encap.setIdNum("12343ms");
       
            System.out.print("Name : " + encap.getName()+ 
                                   " Age : "+ encap.getAge());
          }
      }
      

11、Java 枚举(enum)

  • 概述

    • Java 枚举是一个特殊的类,一般表示一组常量,比如一年的 4 个季节,一个年的 12 个月份,一个星期的 7 天,方向有东南西北等。

    • Java 枚举类使用 enum 关键字来定义,各个常量使用逗号 , 来分割。

      enum Color 
      { 
          RED, GREEN, BLUE; 
      } 
      public class Test
      {
          // 执行输出结果
          public static void main(String[] args)
          {
              Color c1 = Color.RED;
              System.out.println(c1);
          }
      }
      
  • 在 switch 中使用枚举类

    enum Color
    {
        RED, GREEN, BLUE;
    }
    public class MyClass {
      public static void main(String[] args) {
        Color myVar = Color.BLUE;
    
        switch(myVar) {
          case RED:
            System.out.println("红色");
            break;
          case GREEN:
             System.out.println("绿色");
            break;
          case BLUE:
            System.out.println("蓝色");
            break;
        }
      }
    }
    
  • values(),ordinal()和valueOf()方法

    • enum 定义的枚举类默认继承了 java.lang.Enum 类,并实现了 java.lang.Serializable 和 java.lang.Comparable 两个接口。

    • values(), ordinal() 和 valueOf() 方法位于 java.lang.Enum 类中:

      • values() 返回枚举类中所有的值。
      • ordinal()方法可以找到每个枚举常量的索引,就像数组索引一样。
      • valueOf()方法返回指定字符串值的枚举常量。
      enum Color
      {
          RED, GREEN, BLUE;
      }
       
      public class Test
      {
          public static void main(String[] args)
          {
              // 调用 values()
              Color[] arr = Color.values();
       
              // 迭代枚举
              for (Color col : arr)
              {
                  // 查看索引
                  System.out.println(col + " at index " + col.ordinal());
              }
       
              // 使用 valueOf() 返回枚举常量,不存在的会报错 IllegalArgumentException
              System.out.println(Color.valueOf("RED"));
              // System.out.println(Color.valueOf("WHITE"));
          }
      }
      
    • 枚举跟普通类一样可以用自己的变量、方法和构造函数,构造函数只能使用 private 访问修饰符,所以外部无法调用。

      enum Color
      {
          RED, GREEN, BLUE;
       
          // 构造函数
          private Color()
          {
              System.out.println("Constructor called for : " + this.toString());
          }
       
          public void colorInfo()
          {
              System.out.println("Universal Color");
          }
      }
       
      public class Test
      {    
          // 输出
          public static void main(String[] args)
          {
              Color c1 = Color.RED;
              System.out.println(c1);
              c1.colorInfo();
          }
      }
      

12、内部类

在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。

posted @   秋风里的蜜  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
  1. 1 在你的身边 盛哲
  2. 2 世间美好与你环环相扣 柏松
  3. 3 起风了 吴青峰
  4. 4 极恶都市 夏日入侵企划
极恶都市 - 夏日入侵企划
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 王星

作曲 : 灰鸿啊/皮皮

编曲 : 夏日入侵企画

制作人 : 邢硕

节奏吉他 : 肯尼

主音吉他 : 张伟楠

贝斯 : 皮皮

鼓 : 海鑫

和声 : 邢硕

音效制作 : 邢硕

录音 : 邢硕/夏国兴

混音 : 于昊

特别鸣谢 : 张伟楠

这城市的车流和这地表的颤抖

像一颗石子落入地心之后泛起的温柔

暗涌

河水流过转角她的楼

被梦魇

轻声呓语唤醒身后的幼兽

失效感官焦灼只剩下

麻木愚钝无从感受

共同支撑全都瓦解

只是我们现在都

已忘记到底是

谁隐藏春秋

谁在大雨之后

把旗帜插在最高的楼

过去陈旧的还在坚守

内心已腐朽

摇摇欲坠不停退后

毁灭即拯救

夏日掠夺春秋

结局无法看透

眼看这情节开始变旧

所有的城池已失守

最终无法占有

无眠辗转

伴着人间破碎的旧梦

像繁星

退却后只剩下混沌的夜空

炙热

掩盖风声鹤唳的担忧

把所有失落无助反手推入

无尽的白昼

失效感官焦灼只剩下

麻木愚钝无从感受

共同支撑全都瓦解

只是我们现在都已经忘记到底是

谁隐藏春秋

谁在大雨之后

把旗帜插在最高的楼

过去的陈旧还在坚守

内心已腐朽

摇摇欲坠不停退后

毁灭即拯救

夏日掠夺春秋

结局无法看透

眼看这情节开始变旧

所有的城池早已失守

惶恐难以接受

缠绵往复不肯放手

最终无法占有

谁隐藏春秋

谁在大雨之后

把旗帜插在最高的楼

过去的陈旧还在坚守

内心已腐朽

摇摇欲坠不停退后

毁 灭 即 拯 救

谁掠夺春秋

谁在大雨之后

把旗帜插在最高的楼

过去的陈旧还在坚守

内心已腐朽

摇摇欲坠不停退后

毁灭即拯救

夏日掠夺春秋

结局无法看透

明知城池已失守

缠绵往复不肯放手

最终无法占有

点击右上角即可分享
微信分享提示