Java基础


typora-root-url: C:\Users\13799\Pictures\Java

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ehwVPukB-1647855537848)(C:\Users\13799\AppData\Roaming\Typora\typora-user-images\image-20220103123746769.png)]

Java基础

一、Java面向对象基础

1、常识

Windows快捷命令:
  1. Ctrl+C:复制
  2. Ctrl+V:粘贴
  3. Ctrl+A:全选
  4. Ctrl+X:剪切
  5. Ctrl+Z:撤销
  6. windows+r+cmd:命令行窗口
  7. Ctrl+shift+esc:资源管理器
Dos命令:
  • 打开CMD:
  1. 开始+系统+命令提示符
  2. windows+r+cmd:命令行窗口
  • 常用Dos命令:(所有字符都得是英文半角)

    1. 磁盘块名 + : #切换盘块
  1. dir #查看当前盘所有文件目录
  2. cd + … #返回上一级
  3. cd + /d +路径 #跳转到目标路径
  4. cls #清除屏幕
  5. exit #推出
  6. ipconfig #查看电脑ip
  7. ping + 域名 #获得网站的ip
  8. md +目录名 #创建目录
  9. rd +目录名 #删除目录
  10. cd> +文件名 #创建文件
  11. del +文件名 #删除文件

2、java基础

JDK----Java开发环境

JRE---- Java运行环境

JVM----Java虚拟机,跨平台的基础

(向下包含)

1、常用快捷命令:
  1. psvm:主函数(main函数)入口

    public static void main(String[] args) {
       
    }
    
  2. soutv:快速打印方法的参数

        public String toLogin(String uname,String pwd){
            System.out.println("uname = " + uname);
            System.out.println("pwd = " + pwd);
            return "main.jsp";
        }
    }
    
  3. sout:输出语句

    System.out.println()//输出一个就换一行
    System.out.print()//输出之后不换行1public class Demo1 {
        public static void main(String[] args) {
            for (int i = 0; i < 9; i++) {
                System.out.print(i);
            }
        }
    }输出:0123456782public class Demo2 {
        public static void main(String[] args) {
            for (int i = 0; i < 9; i++) {
                System.out.println(i);
            }
        }
    }输出:0
    	  1
    	  2
    	  3
    	  4
    	  5
    	  6
    	  7
    	  8
    
2、Java基础语法
1、注释:

说明代码的功能,规范性编码。

常用有三种:

  • 单行注释:代码后面加上 //注释

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

  • 文档注释(JavaDoc):注释里面可以自己很多需要标注的东西,例如:作者、版本等等 /** 注释 */

/**
 * @Author shkjahfjk
 * @version 1.8
 */
2、标识符和关键字:
  • 关键字:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xYiR4iYJ-1647855537849)(C:\Users\13799\AppData\Roaming\Typora\typora-user-images\image-20220109165209313.png)]

    • public:

    • private:

    • final:定义常量

    • static:定义类变量和静态方法,静态方法可以直接在同一个类中直接调用;

      使用了static的方法会和类一起加载,而未使用的方法只有在类被实例化成对象后才会加载

    • break:强制退出循环,跳出所在的循环体,会继续执行循环体之后的代码

      int i=0;
      while(i<100){
         i++;
         if (i%10==0){
            System.out.println("省略");
            break;//强制退出循环,跳出所在的循环体,会继续执行循环体之后的代码
         }
         System.out.print(i);
      }
      输出:123456789省略
      	 
      
    • continue:退出此次循环,跳到循环体的开始条件处,再次执行循环

      int i=0;
      while(i<50){
         i++;
         if (i%10==0){
            System.out.println("省略");
            continue;//退出此次循环,跳到循环体的开始条件处,再次执行循环
         }
         System.out.print(i);
      }
      输出:123456789省略
      	 111213141516171819省略
      	 212223242526272829省略
      	 313233343536373839省略
      	 414243444546474849省略
      
    • return:方法的返回值,是一个方法中最后一句被执行的语句

  • 标识符:

    类名、变量名以及方法名都叫标识符

    其书写规则有:

    • 只能以字母、$、 _ 这三种开头
    • 除开头外,可以用字母、$、_ 、数字任意组合
    • 不能用关键字来作为类名、变量名或方法名
    • 标识符是大小写敏感的(区分大小写)
    • 一般不用中文或拼音做标识符
  • 数据类型:Java是强类型语言,要求变量的使用要严格符合规定,所有变量都必须先定义(初始化),然后才能使用

    • 基本类型:
      • byte:1个字节
      • short:短整型,2个字节
      • int:整型,4个字节
      • long:长整型,8个字节(须在定义的时候在数字后面加一个L用作区分,如:long num=30L;)
      • float:单精度浮点数,4个字节(须在定义的时候在数字后面加一个F用作区分,如:float num=30.2F;)
      • double:双精度浮点数,8个字节
      • char:字符型,2个字节(char A=‘a’;)
      • string:字符串,不是关键字,是一个类(string A=“abcdefg”;)
      • boolean:布尔型,占一个比特位,只有true和false两种情况(0和1两种情况)
    • 引用类型:
      • 接口
      • 数组
3、数据类型扩展:
  • 不同进制:

    • 八进制(O):如:O45
    • 十六进制(OX):如:OX45
  • 银行业务不能用浮点数类型比较,会有误差,要用数学工具类:BigDecimal

  • 所有的字符本质上是数字,可以通过强制转换成数字。(即按照相应规则的编码方式,如:UTF-8)

  • 转义字符:

    • \t : 制表符
    • \n : 换行

    等等

4、类型转换:

​ Java中的不同类型数据运算时,要先转换成相同类型再来运算,转换顺序(由低到高):

​ byte、short、char -> int -> long -> float -> double

  • 强制类型转换:

    int a=8;
    float b=(float) a;//将int类型强转为float类型
    short c=(short) a;//将int类型强转为short类型
    

    注:强制转换,由高到低强转时可能溢出。

  • 自动类型转换:

    由编译器自动将低优先级类型转换为高优先级类型

    int a=8;
    double c=a;//将int自动转换为double型
    
5、变量、常量、作用域:
  • 变量:可以变化的量,每个变量都需要定义

    • 每个变量必须声明其所属的数据类型

    • 变量声明是一个完整的语句

    • 变量名必须是合法的标识符

      type 变量名 = 变量初始值 ;  //变量定义的方法
      
  • 常量:

    通过final关键字来定义

    public class Hello {
       final static int a=0;//final与static都是修饰符
       static final int b=1;//修饰符不区分前后
       public static void main(String[] args) {
          System.out.println(b);
          System.out.println(a);
       }
    }
    
  • 作用域:

    • 类变量:static 关键字声明的变量,跟实例变量的作用范围一样,但是不用通过对象来调用

      public class Hello {
         
         static int a;
         
         public static void main(String[] args) {
            System.out.println(a);//跟局部变量类似,可直接调用
         }
      }
      
    • 实例变量:在类中,方法外声明的变量,从属于对象,必须通过类来调用

      public class Hello {
      
      	String name="yhx";
      	int age=0;
      	
      	public static void main(String[] args) {
      		Hello hello=new Hello();//new一个Hello的对象hello
      		System.out.println(hello.name);//通过hello对象来调用实例变量name
      
      	}
      }
      
    • 局部变量:在某一个方法内声明并起作用的变量

      public class Hello {
         public static void main(String[] args) {
            int a=0;//局部变量
            System.out.println(a);//直接调用
         }
      }
      

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oHON8rZ8-1647855537849)(C:\Users\13799\AppData\Roaming\Typora\typora-user-images\image-20220114091531255.png)]

6、基本运算符:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LqkiqNHD-1647855537850)(C:\Users\13799\AppData\Roaming\Typora\typora-user-images\image-20220114092040417.png)]

  • %:取余运算,输出余数

    public class Hello {
    
       public static void main(String[] args) {
          int a=9;
          int b=3;
          System.out.println(a%b);
       }
    }
    输出余数:
    输出结果为:0
    
  • 关系运算符:返回值为true或false(布尔值)

  • 自增、自减运算符:++、–

    package Study;
    
    public class Hello {
    
       public static void main(String[] args) {
          int a=1;
          int d=1;
    
          int b=a++;//先给b赋值,再a自增
          System.out.println("b="+b);
          System.out.println("a="+a);
    	  //输出:b=1,a=2
           
          int c=++d;//先d自增,再给c赋值
          System.out.println("d="+d);
          System.out.println("c="+c);
    	  //输出:d=2,c=2
       }
    }
    
  • 位运算:(二进制位的运算)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cZ5EvArE-1647855537850)(C:\Users\13799\AppData\Roaming\Typora\typora-user-images\image-20220114094555200.png)]

    • &:与运算
    • / :或运算
    • ^:异或运算
    • ~:取反(非运算)
    • <<:算数左移(移一位等价于*2)
    • 》:算数右移(移一位等价于/2)
  • 连接符:

    public static void main(String[] args) {
       int a=1;
       int d=1;
       int c=1;
       int b=1;
       System.out.println(a+b+" string类型 "+c+d);
       //在输出语句中:String类型前的+为加号,String后的+为连接符
       //a+b中的+即为加号,c+d中的+即为连接符
       //输出结果:2 string类型 11
    }
    
  • 三元运算符:(? :)

    例:x?y:z

    x为真,则执行y

    x为假,则执行z

    public static void main(String[] args) {
       int a=80;
       int b=50;
       String grade1=a<60?"不及格":"及格";
       String grade2=b<60?"不及格":"及格";
    
       System.out.println(grade1);//及格
       System.out.println(grade2);//不及格
    }
    
7、包机制:
  • 包的本质是文件夹:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A3wgCij4-1647855537851)(C:\Users\13799\AppData\Roaming\Typora\typora-user-images\image-20220114100742997.png)]

  • 一般利用公司域名的倒置为包名:

    如:www.baidu.com

    包名:com.baidu.www

  • 为了使用某一个包内的成员,必须用import将其导入

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3qsITtnx-1647855537852)(C:\Users\13799\AppData\Roaming\Typora\typora-user-images\image-20220114102327185.png)]

8、JavaDoc生成文档:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YYsk2TOu-1647855537852)(C:\Users\13799\AppData\Roaming\Typora\typora-user-images\image-20220114102629220.png)]

3、Java流程控制
1、用户交互:Scanner对象(获取用户输入)
import java.util.Scanner;//引用scanner类
  • 基础语法:
Scanner scanner=new Scanner(System.in);//基础语法
  • 用hasNext()和hasNextLine()方法判断是否还有输入的数据,两个方法用法一致

  • 用Scanner类的next()和nextLine()方法获取输入的字符串;

  • next()的例子:

import java.util.Scanner;//引用Scanner类

public class Hello {

   public static void main(String[] args) {
      Scanner scanner=new Scanner(System.in);//创建一个扫描器对象,用于接受键盘输入

      if(scanner.hasNext()){//利用hasNext()方法来判断是否还有输入

         String str=scanner.next();//利用next()方法来接受输入

         System.out.println(str);
      }
      scanner.close();//IO类最好在用完后手动关闭,以减少资源损耗
   }
}
输入:hellow world
输出:hellow
  • nextLine()的例子:
import java.util.Scanner;//引用Scanner类

public class Hello {

   public static void main(String[] args) {
      Scanner scanner=new Scanner(System.in);//创建一个扫描器对象,用于接受键盘输入

      if(scanner.hasNext()){//利用hasNext()方法来判断是否还有输入

         String str=scanner.nextLine();//利用nextline()方法来接受输入

         System.out.println(str);
      }
      scanner.close();//IO类最好在用完后手动关闭,以减少资源损耗
   }
}
输入:hellow world
输出:hellow world
  • next()和nextLine()的异同:

    next()方法一定要接收到有效的输入才能利用回车输出,有效输入前的空格会被自动省略,有效输入后的空格会导致输入在此退出,不能得到带空格的字符串

    nextLine()方法可以得到回车键之前的所有输入

  • 精简后的代码:(不用判断是否有输入)

    import java.util.Scanner;//引用Scanner类
    
    public class Hello {
    
       public static void main(String[] args) {
          Scanner scanner=new Scanner(System.in);//创建一个扫描器对象,用于接受键盘输入
    
          String str=scanner.nextLine();//利用nextline()方法来接受输入
    
          System.out.println(str);
    
          scanner.close();//IO类最好在用完后手动关闭,以减少资源损耗
       }
    }
    
  • 进阶用法:scanner.next()方法有许多种

    比如:scanner.nextInt()等

2、顺序结构:

Java的基本结构,从上而下依次执行Java语句

3、if选择结构:
  • if单选择结构:

    if(判断条件)

    {

    ​ 判断条件为真时,执行此处代码

    }

  • if双选择结构:

    if(判断条件)

    {

    ​ 判断条件为真时,执行此处代码

    }

    else{

    ​ 判断条件为假时,执行此处代码

    }

  • if多选择结构:

    if(判断条件1)

    {

    ​ 判断条件1为真时,执行此处代码

    }

    else if(判断条件2)

    {

    ​ 判断条件2为真时,执行此处代码

    }

    else if(判断条件3)

    {

    ​ 判断条件3为真时,执行此处代码

    }

    else{

    ​ 所有判断条件都为假时,执行此处代码

    }

  • if嵌套结构

    if(判断条件1)

    {

    ​ 判断条件1为真时,执行此处代码

    ​ if(判断条件2)

    ​ {

    ​ 判断条件2为真时,执行此处代码

    ​ }

    }

4、Switch多选择结构:

switch()中的判断条件只能是byte、short、int或char类型;从1.7版本开始也支持String类型

在Java程序的执行中,将String类型的数据转换成对应的hasCode来进行的判断,不同的字符串对应不同的数字

char grade='c';
switch (grade){
   case 'a':
      System.out.println("优秀");
      break;//每一个case后面都需要一个break。以避免将后面的case都执行了
   case 'b':
      System.out.println("良好");
      break;
   case 'c':
      System.out.println("及格");
      break;
   default://以上所有的case都匹配不了的时候执行
      System.out.println("未知成绩");
}
输入:c
输出:及格
5、循环结构:
  • while循环结构:最基本的循环结构

    先判断后执行

    while(判断条件)

    {

    ​ 只要判断条件为真,则执行此处语句

    }

//输出0~100
int i=0;
while(i<=100){
   System.out.println(i);
   i++;
}

  • do-while循环结构:至少会执行一次

    先执行后判断

    先执行一次,在进行while条件的判断

    do{

    ​ 代码执行区域

    }

    while(判断条件);

     	int i=0;
     	do {
     		System.out.println(i);
     		i++;
     	}while (i>1);
     	//本来是要输出大于1的数,但是用do-while也会输出0
    输出:0
    
    
  • for循环结构:最有效最直接

    for(初始化;判断条件;更新初始值){

    ​ 符合判断条件时,执行此处代码语句

    }

    判断条件为假时,终止循环

//输出0~99的数
for (int i=0;i<100;i++){
   System.out.println(i);
}
4、Java方法
1、方法的定义:
  • 方法的定义:(命名规则:首字母小写及驼峰原则)

    一个由一些语句组成的,能实现一些功能的模块,等价于C++中的函数

    定义:

    修饰符 返回值类型 方法名(参数类型 形参名){

    ​ 方法体

    ​ …

    ​ 返回值(必须与返回类型一致)//如果返回值类型为void,返回值为 return;

    }

    例:

    public static void main(String[] args) {
       int x=5;
       int y=6;
       int sum=add(x,y);//调用add()方法
       System.out.println(sum);
       }
    
    //定义了一个加法方法,static关键字的使用是为了方便调用
    public static int add(int a,int b){
       return a+b;
       }
    
    
2、方法的调用:
  • 当方法不用static修饰时,可以用new一个对象,然后用:

    “new 对象();

    对象名.方法名(参数) ”

    来调用方法

    public class Demo1 {
        public static void main(String[] args) {
            int[] a = {2, 5, 154, 45, 1245, 187, 6, 75, 4};//初始无序数组
    
            Demo1 demo1=new Demo1();//要调用类Demo1中的方法sort,就得先new一个Demo1的对象,此处将该对象命名为demo1
    
            int[] array = demo1.sort(a);//利用对象名.方法名来调用执行冒泡排序算法的方法
            
            System.out.print(Arrays.toString(array));//利用Arrays.toString()方法在输出排序之后的数组
    
        }
    
        //冒泡排序(将大数排在首位)
        public int[] sort(int[] array) {
            int temp = 0;//交换元素时用到的中间变量
    
            //外层循环,数组共有array.length个元素,则最多只需要array.length-1次遍历,所以i < array.length
            //每一次都会将最大的数放在array[i]处,i从0依次增大到最大值,即array.length-1
            for (int i = 0; i < array.length; i++) {
                //内层循环,将已确定次序的大数排出后,所以每一次内循环需要比较的数有j < array.length - 1 - i个,再对剩余的不确定数组比对排序
                for (int j = 0; j < array.length - 1 - i; j++) {
                    if (array[j] < array[j + 1]) {
                        temp = array[j];
                        array[j] = array[j + 1];
                        array[j + 1] = temp;
                    }
                }
    
            }
    
            return array;
        }
    }
    
    
  • 当方法用static修饰时,可以直接调用

     public static void main(String[] args) {
     	int[] array = sort(a);//sort为static来修饰的方法,可以直接调用
     }
    
     public static int[] sort(int[] array) {
       //方法体
     }
    
    • 当方法的返回值不为空时,方法调用通常被当作一个值

      例如:

      int sum=add(x,y);//方法调用被当做一个值
      
      public static int add(int a,int b){
         return a+b;
         }
      
    • 当方法的返回值为空时,方法调用通常是一个语句

      例如:

      System.out.println(sum);//方法调用为一个语句,调用的是println()方法
      
3、方法的重载:
  • 重载就是在同一个类中,拥有方法名相同、但形参不同的方法
//int型的加法add
public static int add(int a,int b){
   return a+b;
   }
//double型的加法add
public  static double add(double a,double b){
   return a+b;
}
  • 方法重载必须要遵守的原则:

    • 方法名必须相同
    • 参数列表必须不同(可以是:参数个数、参数类型、参数排列顺序不同)
    • 方法的返回类型可以相同也可以不相同
    • 仅仅返回类型不同,不能称之为方法的重载
  • 可变参数:

    对一个类型的参数不指定特定的个数

    对double类型的参数不指定个数,注意这种参数只能放在形参列表的最后一个
    public  static void add(double...numbers){
      
    }
    
4、递归:

一个方法自己调用自己

递归结构包括两个部分:

  • 递归头:不再调用自身方法的条件
  • 递归体:调用自身方法的条件
public static void main(String[] args) {
   int a=f(5);
   System.out.println(a);
   }

public static int f(int n){
   if (n==0){
      return 1;
   }
   else if (n==1){
      return 1;
   }
   else{
      return n*f(n-1);//递归调用本身
   }
}
5、Java数组
1、数组的声明和创建:

相同数据类型的数据的有序集合;通过数组下标来访问数组内的某一个数据

注意:数组下标由0开始

  • 声明一个数组:

    数据类型【】+数组名;

  • 创建一个数组:

    数据类型【】+数组名=new 数据类型【数组长度】;

    例子:

int[] array;//声明一个int型数组,array
array=new int[5];//利用new方法,来创建array数组

int[] array1=new int[5];//可将上述两句话统一成一句话,将数组的声明和创建一起完成

System.out.println(array.length);//数组名.length;可以获取数组长度
输出:5

2、三种数组的初始化以及内存分析:
  • Java的内存分为:
    • 堆区:存放new的对象和数组;可以被所有的线程共享,不会存放别的对象引用
    • 栈区:存放基本变量类型(包含此基本类型的具体数值);引用对象的变量(会存放这个引用在堆里的具体地址)
    • 方法区:可以被所有线程共享,包含了所有的class和static变量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pkUgMk8W-1647855537853)(…/JavaSE/java1.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jfP3gvNM-1647855537853)(…/JavaSE/屏幕截图 2022-01-21 100700.png)]

  • 数组的三种初始化方法:

    • 静态初始化:直接给数组赋值

      int[] a={1,2,3};//静态初始化,将数组的大小与每一个下标对应的值都给出
      
      
    • 动态初始化:数组的具体值灵活定义

      //动态初始化
      int[] b=new int[3];//先将数组给声明并创建大小
      //再给每个数组元素分别定义数值
      b[0]=1;
      b[1]=2;
      b[2]=3;
      
      
    • 数组的默认初始化:

      数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化

3、数组下标越界及数组小结:
  • 数组小结

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IqCyeeEZ-1647855537854)(…/JavaSE/QQ截图20220313145151.png)]

  • 数组下标越界:

    数组下标的合法区间:【0,length-1】,超出这个范围则会越界报错。

    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4//数组下标越界报错
    at Study.Demo1.main(Demo1.java:13)//出错的代码行数
    
4、多维数组:
  • 二维数组:

    一个特殊的数组,每一个元素都是一个数组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TLb05O89-1647855537854)(…/JavaSE/QQ截图20220313145243.png)]

  • 定义二维数组:

    • 静态定义二维数组:
    public static void main(String[] args) {
        int[][] a={{1,2},{3,4}};//静态初始化,a[i]为一个数组,a[i][j]为第i+1个数组的第j+1个元素
        for (int i=0;i<a.length;i++){
            for(int j=0;j<a[i].length;j++)
            {
                System.out.print(a[i][j]);
            }
            System.out.println();
        }
    }
    输出:12//数组a[0]中的元素
    	 34//数组a[1]中的元素
    
    • 动态定义二维数组:
    int[][] a=new int[2][2];//动态初始化,只给出一维数组的个数,以及每一个一维数组的元素个数
    
    //a[i]为一个数组,a[i][j]为第i+1个数组的第j+1个元素
    
    //以循环遍历的方式给二维数组的每一个元素赋值,从0开始
    int n=0;
    for (int i=0;i<a.length;i++){
        for (int j=0;j<a[i].length;j++){
            a[i][j]=n;
            n++;
        }
    }
    //循环输出二维数组中的每一个元素
    for (int i=0;i<a.length;i++){
        for(int j=0;j<a[i].length;j++)
        {
            System.out.print(a[i][j]);
        }
        System.out.println();
    }
    
    
5、Arrays类:

​ Java提供的一个关于数组的工具类

例如:

​ //Arrays.toString()方法,可以将a数组打印出来

​ System.out.println ( Arrays.toString(a));

6、冒泡排序:
public static void main(String[] args) {
    int[] a = {2, 5, 154, 45, 1245, 187, 6, 75, 4};//初始无序数组

    int[] array = sort(a);//调用冒泡排序算法
  
    System.out.print(Arrays.toString(array));//利用Arrays.toString()方法在输出排序之后的数组
}

//冒泡排序(将大数排在首位)
public static int[] sort(int[] array) {
    int temp = 0;//交换元素时用到的中间变量

    //外层循环,数组共有array.length个元素,则最多只需要array.length-1次遍历,所以i < array.length
    //每一次都会将最大的数放在array[i]处,i从0依次增大到最大值,即array.length-1
    for (int i = 0; i < array.length; i++) {
        //内层循环,第i大的数已排好序,所以每一次内循环需要比较的数只有有j < array.length - 1 - i个
        for (int j = 0; j < array.length - 1 - i; j++) {
            if (array[j] < array[j + 1]) {//如果要求将小数排在首位,则array[j] > array[j + 1]即可
                temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
            }
        }
    }
  //将最终生成的数组返回,即为冒泡排序后的数组
    return array;
}
7、稀疏数组:

​ 用来存贮稀疏矩阵

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M7r7Krly-1647855537855)(…/JavaSE/QQ截图20220313145313.png)]

6、Java类与对象
1、什么是面向对象(oop):
  • 以类的方式组织代码,以对象来封装数据
  • 三大特性:
    • 封装:将数据包装起来,对外只提供接口进行访问
    • 继承:父类和子类之间存在继承关系,子类具有父类的所有相关功能
    • 多态:
2、引用传递和值传递:
public class Demo2 {
    public static void main(String[] args) {
        Person person=new Person();

        System.out.println(person.name);//输出null


        change(person);
        System.out.println(person.name);//输出yhx
    }
    public static void change(Person person){
        //person是一个对象:指向的是--->Person person=new Person();是一个具体的人,所以可以改变属性name
        person.name="yhx";
    }
}

//新建一个class,(注意,一个.java中只能有一个public class);没有public修饰符的类只能在该.java文件中调用
class Person{
    String name;//Person的属性
}
3、类与对象的关系:
  • 类:是一个抽象的数据类型,是对某一类事物的整体描述、定义,但是并不能代表某一个具体的事务

    //Person 就是一个类
    class Person{
        String name;//Person的属性
    }
    
  • 对象:是抽象概念的集体实例

//fact_person就是一个对象
public class Demo2 {
    public static void main(String[] args) {
        Person fact_person=new Person();//利用new关键字来创建一个Person类的实例对象fact_person
        System.out.println(fact_person.name);//输出null
        
        change(fact_person);
        System.out.println(fact_person.name);//输出yhx
    }
    public static void change(Person person){
        //person是一个对象:指向的是--->Person person=new Person();是一个具体的人,所以可以改变属性name
        person.name="yhx";
    }
}
4、构造器详解:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nKqxwdQw-1647855537856)(…/JavaSE/QQ截图20220313145339.png)]

//Person类,被Demo2类调用
package Study;

public class Person {
        String name;//属性

        //一个类什么也不写也会有一个方法,这个方法就是构造器(编译器会隐式构造)
  
        //显示定义该构造器 (构造器的名字与类名相同,且不能有返回值)
        public Person(){
        }

        //一旦显示定义一个有参构造器,则必须将无参构造器显示构造出来
        public Person(String name){
                this.name=name;
        }
}

//Demo2类,里面有主函数
package Study;

public class Demo2 {
    public static void main(String[] args) {
        //使用new关键字时,就是去Person类中去使用构造器构造一个实例出来
        Person yhx=new Person();//new一个无参构造器的Person对象:yhx
        Person xry=new Person("我是许润云");//new一个有参构造器的Person对象:xry

        System.out.println(yhx.name);//无参构造器只生成了一个对象,对象的属性为初始值
        System.out.println(xry.name);//有参构造器不仅生成了一个对象,还在方法内部对name属性赋了值
    }

}
输出:null
	 我是许润云

/*总结:
        构造器:
                1、名字和类名相同
                2、没有返回值
        作用:
                1、new方法生成对象时就是在调用构造器
                2、可以利用有参构造器给对象初始化值
        注意:
                当定义了一个有参构造器时,如果还想调用无参构造器,必须把无参构造器显式的构造出来         
         */
private Course course;
//当类中有类属性或集合属性的时候,在构造方法中需要声明该类的对象或者集合的对象,
//例如此处的course为Course类的类属性,因此在构造方法中需要new一个Course的对象
public Stu_Course() {
    this.course=new Course();
}
public Stu_Course(Date time) {
    this.time = time;
    this.course=new Course();
}

  • 可以通过alt+insert来快捷创建构造器:

    先alt+insert,再点击Constructor,进去选择自己需要的参数组合即可

    最下面的Select None则表示生成无参构造器

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kzoiY9xK-1647855537856)(…/JavaSE/QQ截图20220313145416.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JKT4u8s7-1647855537857)(…/JavaSE/QQ截图20220313145422.png)]

5、创建对象的内存分析:(栈区、堆区、方法区)
  • 堆区:存放new的对象和数组;可以被所有的线程共享,不会存放别的对象引用
  • 栈区:存放基本变量类型(包含此基本类型的具体数值);引用对象的变量(会存放这个引用在堆里的具体地址)
  • 方法区:可以被所有线程共享,包含了所有的class和static变量(也在堆里面)
//Pet类,被调用生成对象
package Study;

public class Pet {
    public String name;
    public int age;

    public void shout(){
        System.out.println("叫了一声:哎哟~");
    }
}


//含有主函数
package Study;

public class Demo2 {
    public static void main(String[] args) {
       Pet dog=new Pet();
       dog.name="旺旺";
       dog.age=1;
       dog.shout();

       Pet cat=new Pet();

    }

}

该程序的内存分配示意图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NI3jiKSX-1647855537857)(…/JavaSE/QQ截图20220313145453.png)]

6、类与对象的小结:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zXx5bL9z-1647855537858)(…/JavaSE/QQ截图20220313145503.png)]

7、Java三大特性(封装、继承、多态)
1、封装:(高内聚、低耦合)
  • 高内聚:类的内部数据操作细节由自己完成,不允许外部干涉

  • 低耦合:仅仅暴露少量的方法给外部使用

  • 封装即为数据的隐藏,禁止直接访问一个对象中数据的实际表示,应该通过操作接口来访问,即信息隐藏

  • 封装的好处:

    • 提高程序的安全性,保护数据
    • 隐藏代码的实现细节
    • 统一接口
    • 系统的可维护性增加
  • 注意:属性要私有化, 利用get/set 方法来调用

    get/set方法生成快捷方式:先Alt+insert,再选择Getter或Setter

    get/set方法:内部还可以设计一些条件判断的语句

//调用的类
package Study;
//类
public class Demo3 {
    //属性(封装一般是对于属性来说):私有属性,其他的类不再能够直接调用这些私有属性,只能通过方法来调用
    private String name="老杨";

    private int age;

    private char sex;

    //get 方法:获得这个属性数据,为外部提供一个调用该属性的接口
    public String getName(){
        return this.name;
    }

    //set 方法:给私有属性设置值,为外部提供一个修改本类中私有属性的接口
    public void setName(String name){
        this.name=name;
    }

}

//主函数所在的类
package Study;
public class Demo2 {
    public static void main(String[] args) {
        Demo3 student=new Demo3();

        String name1=student.getName();//通过get方法获得私有属性
        System.out.println(name1);

        student.setName("杨辉祥");//通过set方法为私有属性设置值
        String name2=student.getName();//通过get方法获得新的属性值
        System.out.println(name2);

    }

}
输出:老杨
	 杨辉祥

2、继承
2.1、继承:
  • 继承的本质是对某一批类的抽象,将它们共同的特点提取出来,其他的类可以继承这些抽象类的所有功能
  • 关键字是:extends
  • 子类是父类的扩展,子类继承父类,子类可以继承拥有父类的所有公共方法和公共属性(public修饰的)
  • new一个子类的对象时,除了启动自身的构造器,还会自动的启动父类的构造器
//父类
package Study;
public class Person {
  		
  
        //父类的公共方法可以被子类继承
        public void say(){
                System.out.println("我是你爹");
        }
}

//子类
package Study;
//学生也是人,是人的子类
public class Student extends Person {
        //没有方法,但是继承了父类的公共方法
}

//主函数
package Study;
public class Demo2 {
    public static void main(String[] args) {
        Student student=new Student();//生成一个学生对象
        student.say();//学生类Student可以调用父类Person中的公共方法
    }
}
输出:我是你爹
  • 在Java中,所有类都默认继承Object类
  • Java中只有单继承,没有多继承(也就是只能由一个直接父类)
2.2、super/this:
  • super:调用父类中的公共属性或公共方法

  • this:调用当前类中的属性或方法

  • 例1:super/this调用属性

    //父类
    package Study;
    
    public class Person {
           protected String name="yhx";//父类的属性
    }
    
    //子类
    package Study;
    //学生也是人,是人的子类
    public class Student extends Person {
        private String name="rxy";//子类的属性
    
        public void test(String name){
            System.out.println(name);//name表示当前方法被调用时传过来的实参
            System.out.println(this.name);//this.name表示调用当前类的属性name
            System.out.println(super.name);//super.name表示调用父类中的属性name
        }
    }
    
    //主函数
    package Study;
    public class Demo2 {
        public static void main(String[] args) {
            Student student=new Student();
            student.test("马牛逼");//调用Student类中的test()方法,并且将实参传送过去
        }
    }
    输出:马牛逼
    	 rxy
    	 yhx
    
  • 例2:super/this调用方法

    //父类
    package Study;
    public class Person {
           //父类的print()方法
           public void print(){
                  System.out.println("我是你爹");
           }
    }
    
    //子类
    package Study;
    //学生也是人,是人的子类
    public class Student extends Person {
        //子类的print()方法
        public void print(){
            System.out.println("我是儿子");
        }
    
        public void test(){
            print();//调用本类中的print()方法
            this.print();//调用本类中的print()方法
            super.print();//调用父类中的print()方法
        }
    }
    
    //主函数
    package Study;
    public class Demo2 {
        public static void main(String[] args) {
            Student student=new Student();
            student.test();//调用Student类中的test()方法
        }
    }
    输出:我是儿子
    	 我是儿子
    	 我是你爹
    

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GhxGH7v4-1647855537858)(…/JavaSE/QQ截图20220313145546.png)]

2.3、方法重写(与方法重载不同):
  • 重写都是指方法,与属性无关
  • 重写了的方法,一旦执行,执行的就是被重写后的方法体
  • 只能子类重写父类的public方法
  • 不能被重写的方法:
    • static修饰的静态方法
    • final修饰的常量
    • private修饰的私有方法
  • 为什么需要重写:
    • 父类的功能,子类不一定需要,或者不一定能够满足
    • 快捷键:先Alt+Insert,再选择override

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QNrO7FJA-1647855537865)(…/JavaSE/QQ截图20220313145615.png)]

3、多态(只是方法才能说多态)
  • 一个对象的实际类型是确定的;例如:new Student();//实际类型即为Student类

  • 但是实际类型可以指向的引用类型就不确定了,可以指向父类或者祖宗类

    例如:

    Student s1 = new Student();//s1的实际类型为Student,指向的引用类型为Student
    Person s2 = new Student();//s2的实际类型为Student,指向的引用类型为其父类Person
    Object s3 = new Student();//s3的实际类型为Student,指向的引用类型为其祖宗类Object
    
//父类
package com.yhx.demo_duotai;
public class Person {
    public void run(){
        System.out.println("父类run");
    }
}

//子类
package com.yhx.demo_duotai;
public class Student extends Person {
    @Override
    public void run() {
        System.out.println("子类run");
    }

    public void eat(){
        System.out.println("子类eat");
    }
}

//主函数
package com.yhx;
import com.yhx.demo_duotai.Person;
import com.yhx.demo_duotai.Student;
public class Main_class {
    public static void main(String[] args) {
        Student s1 = new Student();//s1的实际类型为Student,指向的引用类型为Student
        Person s2 = new Student();//s2的实际类型为Student,指向的引用类型为其父类Person
        Object s3 = new Student();//s3的实际类型为Student,指向的引用类型为其祖宗类Object

        //对象能调用什么方法,主要看对象定义等式的左边部分所表示的类有哪些可执行的方法(包括继承过来的方法)
        s1.run();
        s2.run();//子类重写了父类的方法,所以执行子类的方法体

        s1.eat();
        s2.eat();//出错了,Person类中没有eat()方法,父类的对象只可以指向子类被重写了的方法,不可以调用子类独有的方法
    }
}
8、Java扩充
1、instanceof关键字和类型转换:
  • 类型转换:

    /*
    1、父类的引用指向子类的对象
    2、把子类转换成父类,向上转型,可以自动转换,会丢失自己的一些方法
    3、把父类转换成子类,向下转型,需要强制转换
    */
    
    //类型之间的转换:父--》子 (高级--》低级)
    Person s1 = new Student();//对象s1为Person类型(父类的引用指向了子类的对象)
    //方法一:将s1转变成Student类型,那么转换后的对象就可以使用Student类中的方法了
    Student student=(com.yhx.demo_duotai.Student)s1;//括号内写出强转的类即可
    student.go();
    //方法二:或者可以这样强行转换类型
    ((Student)s1).go();
    
    //子类转换成父类,会丢失自己的一些方法
      Student student1=new Student();
      student1.go();
      Person person=student1;//将student1转换成父类Person,子类转换成父类可以自动转换
    
  • Instanceof

    判断两个类之间是否有父子关系,判断一个对象是什么类型的

    //Object》Person》Student
    //Object》Person》Teacher
    //Object》String
    Object object=new Student();//object对象为Object类型
    
    System.out.println(object instanceof Student);//true,Object类是Student类的父类
    System.out.println(object instanceof Person);//true,Object类是Person类的父类
    System.out.println(object instanceof Object);//true,Object类是Object类的父类
    System.out.println(object instanceof Teacher);//false,Object类不是Tercher类的父类
    System.out.println(object instanceof String);//false,Object类不是String类的父类
    
2、static详解:
  • 静态属性:

    private static int age;//静态变量
    private double score;//非静态变量
    
    public static void main(String[] args) {
        Student s1=new Student();
    
        System.out.println(Student.age);//静态变量可以直接使用类名调用,也可以利用对象调用
    
        System.out.println(s1.score);//非静态变量要先新建一个对象,通过对象调用
    
  • 静态方法:

    
    package com.yhx.demo_static;
    public class Student {
    public static void main(String[] args) {
          Student.go();//静态方法可以直接调用
    
          Student s1 = new Student();
          s1.run();//非静态方法只能通过对象调用
      }
    
      //非静态方法
      public void run(){
          System.out.println("run");
      }
    
      //静态方法
      public static void go(){
          System.out.println("go");
      }
    } 
      
    
  • 静态代码块

    package com.yhx.demo_static;
    
    public class Person {
        //每一次对象生成的时候,在构造器之前执行
        //可以用来给对象的生成赋一些初值
        {
            System.out.println("匿名代码块");
        }
    
        //静态代码块
        //在类的加载的时候就执行,在匿名代码块和构造器之前执行,只会执行一次
        static {
            System.out.println("静态代码块");
        }
     
        public Person() {
            System.out.println("构造器");
        }
    
        public static void main(String[] args) {
            Person person1 = new Person();
            System.out.println("=================================");
            Person person2 = new Person();
        }
    }
    输出:
    静态代码块
    匿名代码块
    构造器
    =================================
    匿名代码块
    构造器
    
    
3、抽象类:
/*
抽象类的特点:
    1、不能new这个抽象类,只能靠子类去实现它
    2、抽象方法必须在抽象类中
    3、抽象类也可以写普通方法
 */

package com.yhx.demo_abstractClass;
//抽象类
//用abstract关键字来修饰class的类即为抽象类
public abstract class Action {
    //用abstract来修饰方法名,即为抽象方法
    //抽象方法,只有方法名字,没有方法体
    public abstract void doSomething();
    
}

4、接口:

声明接口的关键字是interface,声明类的关键字是class

  • 接口的本质是契约,如同我们的法律,制定好了就要去遵守

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uRWXOKbK-1647855537866)(…/JavaSE/QQ截图20220313145652.png)]

//接口1
package com.yhx.demo_interface;

//定义接口的关键字:interface
public interface UserService {
    //接口定义的所有属性都是一个常量,默认为常量(public static final);而且一般不在接口中定义属性
    int age=99;

    //接口中的所有方法的定义都是抽象的,默认为 public abstract
    //接口的方法都只有定义,没有具体实现;因此需要一个类来实现接口的方法
    public abstract void add(String name);
    void delete(String name);
    void insert(String name);
    void select(String name);
}

//接口2
package com.yhx.demo_interface;

public interface TimeService {
    void timer();
}

//实现接口的类
package com.yhx.demo_interface;

//一个类通过关键字:implements加上一个接口,来实现一个接口
//一个类可以实现多个接口,只要将所有接口的方法都重写即可
public class UerServiceImpl implements UserService,TimeService{
    //要实现一个接口,就必须在类中重写接口的所有方法
    @Override
    public void add(String name) {

    }

    @Override
    public void delete(String name) {

    }

    @Override
    public void insert(String name) {

    }

    @Override
    public void select(String name) {

    }

    @Override
    public void timer() {

    }
}
5、多种内部类:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mz35a9Q3-1647855537866)(…/JavaSE/QQ截图20220313145715.png)]

1、成员内部类
  • 内部类可以调用外部类的私有属性和私有方法
//成员内部类的定义
package com.yhx.demo_insideClass;

public class Outer {
    //外部类的私有属性
    private int id=10;

    //外部类的公共方法
    public void out(){
        System.out.println("这是外部类的方法");
    }

    //内部类:定义在一个类内部的类;定义方法和外部类一样
    public class Inner{
        //内部类的方法
        public void in(){
            System.out.println("这是内部类的方法");
        }

        //内部类可以操作外部类的私有属性和私有方法
        public void getId(){
            System.out.println(id);
        }

    }
}

//主函数
package com.yhx;
import com.yhx.demo_insideClass.Outer;
public class Main_class {
    public static void main(String[] args) {
        Outer outer = new Outer();//实例化一个外部类的对象

        //通过外部类的对象来实例化内部类的对象
        Outer.Inner inner = outer.new Inner();

        inner.in();
        inner.getId();
    }
}
输出:
这是内部类的方法
10
2、静态内部类
package com.yhx.demo_insideClass;

public class Outer {
    //外部类的私有属性
    private int id=10;

    //外部类的公共方法
    public void out(){
        System.out.println("这是外部类的方法");
    }

    //静态内部类:定义在一个类内部的类,加了一个static关键字
    //静态内部类不可以操作外部类的非静态私有属性和非静态私有方法
    public static class Inner{
        //内部类的方法
        public void in(){
            System.out.println("这是内部类的方法");
        }
        
    }
}
3、局部内部类

写在外部类的方法中的类

package com.yhx.demo_insideClass;
//外部类
public class Outer {
    //外部方法
    public void A(){
        //外部方法中写的内部类:局部内部类
        class Inner{
            //内部方法
            public void in(){

            }
        }
    }
}
4、匿名内部类
package com.yhx.demo_insideClass;

public class Test {
    public static void main(String[] args) {
        //没有名字初始化类,不用将实例保存到变量中

        new A().eat();

        //没有名字初始化实现接口的类
        new UserService(){
        	//重写接口的方法
            @Override
            public void hello() {
            }
        };
    }
}

class A{
    public void eat(){
        System.out.println("这是A中的eat方法");
    }
}

interface UserService{
    void hello();
}
9、异常

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gETiHsHR-1647855537867)(…/JavaSE/QQ截图20220313145736.png)]

1、Java异常体系结构:
  • Java把异常当作对象来处理,并且定义了一个基类java.lang.Throwable作为所有异常的超类。
  • 在Java API中已经定义了许多异常类,这些异常类分为错误Error和异常Exception这两大类。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yCR94cZZ-1647855537867)(…/JavaSE/QQ截图20220313145754.png)]

  • 错误Error:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P3LhGUqO-1647855537868)(…/JavaSE/QQ截图20220313145800.png)]

  • 异常Exception:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rpM7i3gH-1647855537869)(…/JavaSE/QQ截图20220313145805.png)]

2、异常处理机制:

异常处理的五个关键字:try、catch、finally、throw、throws

  • 捕获异常:(try、catch、finally)

    try—catch—finally快捷生成方式:先选中要捕捉异常的代码,再Ctrl+Alt+T,然后在下拉框中选择要生成的结构

package com.yhx.demo_exception;

public class Demo1 {
    public static void main(String[] args) {
        //关键字try用来监控某一代码块是否有异常
        try{
            Demo1 demo1 = new Demo1();
            demo1.A();
        }
        //一旦出现了catch后面括号中的错误类型,就执行下面区域的代码
        //如果try中的代码出现的错误不是catch后面括号中的错误类型,就捕捉不到该异常
        //Exception类型的异常是所有异常的父类,如果括号中是Exception则可以捕获所有类型的异常
        //catch可以跟if—else一样有多层判断,而且判断范围是Error<Exception<Throwable;小的判断范围要写在大的范围的前面
        catch (Error e){
            System.out.println("这是一个错误");
        }
        catch (Exception e){
            System.out.println("这是一个异常");
        }
        catch (Throwable e){
            System.out.println("这是一个Throwable");
        }
        //不管异常监控区域是否出现错误,都会执行此处代码;用来进行善后的工作
        finally {
            System.out.println("程序异常检测完毕");
        }
        /*
        1、try和catch必须成对出现
        2、finally可有可无,可以用来处理一些善后工作
         */
    }
    public void A(){
        B();
    }
    public void B(){
        A();
    }
}

  • 抛出异常:(throw、throws)
package com.yhx.demo_exception;

public class Demo2_throwException {
    public static void main(String[] args) {
        new Demo2_throwException().test(1,0);
    }
	
  	//假设该方法中有出现异常的条件,就可以主动抛出这个异常
    public void test(int a,int b){
        if (b==0){
            //主动抛出异常:throw
            //一般在方法中使用,即使并未实际运行a/b,也可以使它主动抛出相应的错误
            throw new ArithmeticException();
        }
    }

}
  • 异常处理的好处:

    可以在catch代码块里面解决掉可以预见的一些异常,使得程序发生一些可预见错误的时候不用终止程序,而是按照catch中的处理方法继续运行程序

3、自定义异常:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QhQfGesV-1647855537869)(…/JavaSE/QQ截图20220313145848.png)]

package com.yhx.demo_exception;

//自定义异常类,只需要将自己创建的类继承Exception类即可   
public class Demo4_myException extends Exception {
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rXBCBn83-1647855537870)(…/JavaSE/QQ截图20220313145913.png)]

10、泛型:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lCXRHMAg-1647855537870)(…/JavaSE/QQ截图20220313145931.png)]

即加了泛型之后,实际传入的数据类型一定要和规定好的泛型一致;也可以使用来表示匹配所有类型

10.1泛型类:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DRbdMJcE-1647855537871)(…/JavaSE/QQ截图20220313145952.png)]


/*
声明泛型类的对象的时候:一定要指明该对象的类型
例如:
	Test2<String> test=new Test2<String>();

*/
package com.yang.Demo1;

public class Test2<T>{
    private T a;

    public T getA() {
        return a;
    }

    public void setA(T a) {
        this.a = a;
    }
}
10.2泛型方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tcJ0PYJT-1647855537871)(…/JavaSE/QQ截图20220313150009.png)]

package com.yang.Demo1;

public class Test3 {
    public static void main(String[] args) {
        Generics g = new Generics();
        g.run("阿巴阿巴");
        g.run(1234);
        g.run(true);

    }
}

class Generics{
    //定义一个泛型方法
    public <T>  void run(T t){
        System.out.println(t);
    }
}
10.3泛型接口:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PIFgQ3yT-1647855537872)(…/JavaSE/QQ截图20220313150028.png)]

//泛型接口的定义
package com.yang.Demo2;
public interface testInterface <T> {
    void run(T t);
}

//泛型接口的实现类
package com.yang.Demo2;
public class  testInterfaceImpl<T> implements testInterface<T>{
    @Override
    public void run(T t) {
        System.out.println(t);
    }
}

//主函数
package com.yang.Demo2;
public class Test {
    public static void main(String[] args) {
        testInterfaceImpl<String> A = new testInterfaceImpl<>();
        A.run("阿巴阿巴");

        testInterfaceImpl<Integer> B = new testInterfaceImpl<>();
        B.run(10);
    }
}
//假设该方法中有出现异常的条件,就可以主动抛出这个异常
public void test(int a,int b){
    if (b==0){
        //主动抛出异常:throw
        //一般在方法中使用,即使并未实际运行a/b,也可以使它主动抛出相应的错误
        throw new ArithmeticException();
    }
}

}


- 异常处理的好处:

  可以在catch代码块里面解决掉可以预见的一些异常,使得程序发生一些可预见错误的时候不用终止程序,而是按照catch中的处理方法继续运行程序

###### 3、自定义异常:

[外链图片转存中...(img-QhQfGesV-1647855537869)]

```Java
package com.yhx.demo_exception;

//自定义异常类,只需要将自己创建的类继承Exception类即可   
public class Demo4_myException extends Exception {
}

[外链图片转存中…(img-rXBCBn83-1647855537870)]

10、泛型:

[外链图片转存中…(img-lCXRHMAg-1647855537870)]

即加了泛型之后,实际传入的数据类型一定要和规定好的泛型一致;也可以使用来表示匹配所有类型

10.1泛型类:

[外链图片转存中…(img-DRbdMJcE-1647855537871)]


/*
声明泛型类的对象的时候:一定要指明该对象的类型
例如:
	Test2<String> test=new Test2<String>();

*/
package com.yang.Demo1;

public class Test2<T>{
    private T a;

    public T getA() {
        return a;
    }

    public void setA(T a) {
        this.a = a;
    }
}
10.2泛型方法:

[外链图片转存中…(img-tcJ0PYJT-1647855537871)]

package com.yang.Demo1;

public class Test3 {
    public static void main(String[] args) {
        Generics g = new Generics();
        g.run("阿巴阿巴");
        g.run(1234);
        g.run(true);

    }
}

class Generics{
    //定义一个泛型方法
    public <T>  void run(T t){
        System.out.println(t);
    }
}
10.3泛型接口:

[外链图片转存中…(img-PIFgQ3yT-1647855537872)]

//泛型接口的定义
package com.yang.Demo2;
public interface testInterface <T> {
    void run(T t);
}

//泛型接口的实现类
package com.yang.Demo2;
public class  testInterfaceImpl<T> implements testInterface<T>{
    @Override
    public void run(T t) {
        System.out.println(t);
    }
}

//主函数
package com.yang.Demo2;
public class Test {
    public static void main(String[] args) {
        testInterfaceImpl<String> A = new testInterfaceImpl<>();
        A.run("阿巴阿巴");

        testInterfaceImpl<Integer> B = new testInterfaceImpl<>();
        B.run(10);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值