【JavaSE进阶学习笔记】

JavaSE进阶学习笔记

Author:Jay



前言

JavaSE进阶是对Java基础进一步的提升,内容更加全面深入,如:对Java面向对象编程进行深入剖析,同时全
面讲解常用API,集合框架、IO流体系、通信原理、并发编程、Java高级技术、JDK新特性、底层源码、设计模式
等,本阶段均一网打尽,并配备了大量的实战案例。
学习目标:

  • 全面学习Java语言体系,获得极强的Java语言功底,能熟练使用Java编程,轻松应对Java
    基础面试

  • 深入理解Java面向对象相关知识点

  • 掌握常用类如集合、IO流、时间日期等操作

  • 掌握Java异常处理机制,熟悉Java多线程开发

  • 掌握网络基础知识,了解Socket原理,TCP、UDP协议

  • 熟悉Java11新特性,如Lambda、Stream流等操作

  • 掌握Java基本语法完成单机系统的编写


提示:以下是本篇文章正文内容,下面案例可供参考

一、面向对象高级

1.静态关键字static

(1)静态变量

  • static是静态的意思,被static修饰的变量被称为静态变量或类变量
  • 静态变量在内存中只有一份,可以被所有对象共享访问、修改。
  • 静态变量可以使用类名或对象名访问,推荐使用类名访问。

格式:static 数据类型 变量名;
举例:public static String country;

静态变量内存原理:
在这里插入图片描述

静态变量和实例变量的区别:
在这里插入图片描述

(2)静态方法

静态方法和实例方法的区别
在这里插入图片描述
静态方法使用注意:

  • 静态方法只能访问静态成员(静态变量、静态方法),不能直接访问实例成员。
  • 静态方法中不能使用this,super等关键字
    应用场景:
  • 如果方法是以执行通用功能为目的,为了方便访问,即可以设计成静态方法。
  • 如果方法中需要访问对象的实例变量,则该方法必须定义成实例方法。

(3)静态方法应用——工具类

工具类的作用:

  • 将应用程序中通用的功能,抽取成静态方法,独立封装成工具类,以便其他地方调用。
  • 作用:方便方法调用,提高代码复用。

工具类的特点

  • 工具类的构造方法通常使用private修饰,不让外界创建对象。
  • JDK的java.util包中,有很多非常实用的工具类,如Arrays,Math等。

2.继承(extends)

(1)继承概述和优点

什么是继承?

  • 继承是将多个类的相同属性和行为抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承单独这个类即可使用这些属性和行为了。
  • 多个类称为子类(派生类),单独的这个类称为父类(基类 或超类)

格式:public class 子类名 extends 父类名 { }

继承的优点

  • 继承的出现减少了代码冗余,提高了代码的复用性。
  • 继承更有利于功能的拓展,子类继承一个父类就得到了父类的功能了。

(2)继承的特点

  • Java只支持单继承,不支持多继承,但支持多层继承。

子类到底能继承父类中的哪些内容?
在这里插入图片描述

继承中成员变量和成员方法的访问特点

  • 遵循就近原则
  • 在子类中,可以通过super关键字,指定访问父类的变量或方法

格式:
super.父类成员变量;
super.父类成员方法();
]

在这里插入图片描述

(3)方法重写
什么是方法重写?

  • 子类中对父类已有的方法重新实现功能。
  • 当子类和父类有相同的功能,但父类的该功能不满足子类的需求时,子类可以重写父类中的方法。
    举例
  • 动物都具备进食的行为eat。
  • 猫和狗都继承动物类,也继承了eat方法。但是猫和狗具体进食的表现不同,所以需要重写父类的eat方法。
    概念区分:
  • 重写:父类和子类之间,子类对父类方法重新实现。(父子类的方法关系)
  • 重载:同一个类中,方法名相同,参数列表不同的两个方法,构成重载。(同个类中的方法关系)

方法重写的格式
在这里插入图片描述

(4)this与super 总结
在这里插入图片描述

3.多态

(1)多态的定义和前提

  • 多态: 是指同一行为,具有多个不同表现形式。
    前提【重点】
  • 1.有继承或实现关系
  • 2.方法的重写
  • 3.父类引用指向子类对象/接口指向实现类

(2)多态的运行特点

  • 调用成员变量时:编译看左边,运行看左边
  • 调用成员方法时:编译看左边,运行看右边

(3)多态的弊端

  • 无法访问子类的独有功能

(4)引用类型转换

  • 向上转型:多态本身是子类类型向父类类型向上转换(自动转换)的过程,这个过程是默认的。
    当父类引用指向一个子类对象时,便是向上转型。

  • 向下转型:父类类型向子类类型向下转换的过程,这个过程是强制的。
    一个已经向上转型的子类对象,将父类引用转为子类引用,可以使用强制类型转换的格式,便是向下转型。

  • 为了避免ClassCastException的发生,Java提供了 instanceof 关键字,给引用变量做类型的校验,格式如下:

变量名 instanceof 数据类型
如果变量属于该数据类型或者其子类类型,返回true。
如果变量不属于该数据类型或者其子类类型,返回false。

public class Test {
    public static void main(String[] args) {
        Animal animal = new Dog();
        animal.eat();
        //多态的弊端 :不能调用子类的特有功能
        //animal.lookHome(); 会报错

        //怎么解决?
        //强转成子类类型
        //细节:转换的时候不能瞎转,如果是其他类的类型,就会报错。

                //jdk14新特性
        if (animal instanceof Dog d){
            d.lookHome();
        }else if (animal instanceof Cat c){
            c.catchMouse();
        }else{
            System.out.println("没有这个类型,无法转换");
        }
    }
}
class Animal{
    public void eat(){
        System.out.println("动物在吃东西");
    }
}

class Cat extends Animal{
    public void eat(){
        System.out.println("猫在吃小鱼干");
    }

    public void catchMouse(){
        System.out.println("猫在抓老鼠");
    }
}

class Dog extends Animal{
    public void eat(){
        System.out.println("狗在啃骨头");
    }
    public void lookHome(){
        System.out.println("狗在看家");
    }
}

4.包和导包

(1)什么是包?

  • 包是用来分门别类的管理各种不同技术类的,类似于文件夹、建包利于技术的管理和维护
  • 建包的语法格式:公司域名反写.技术名称。包名建议全部英文小写,且具备意义

在这里插入图片描述

(2)什么是导包?

  • 相同包下的类使用无需导包,java.lang包下的类无需导包
  • 其他情况下的类使用时需要导包。
  • 导包格式:import 包名.类名;

5.权限修饰符

什么是权限修饰符?

  • 权限修饰符:用来控制成员能够被访问的范围。
  • 可以修饰成员变量,方法,构造器,类,不同权限修饰符修饰的成员能够被访问的范围是不同的。

在这里插入图片描述

6.final关键字

final:不可改变,最终的含义。可以用于修饰类、方法和变量。

  • 类:被修饰的类,不能被继承
  • 方法:被修饰的方法,不能被重写
  • 变量:被修饰的变量,有且仅能被赋值一次

7.抽象类

(1)抽象类

  • 抽象方法 : 没有方法体的方法。
  • 抽象类:包含抽象方法的类。

如果一个类包含抽象方法,那么该类必须是抽象类。注意:抽象类不一定有抽象方法,但是有抽象方法的类必须定义成抽象类。

定义格式:
abstract class 类名字 {
}

(2)抽象类的使用
要求:继承抽象类的子类必须重写父类所有的抽象方法。否则,该子类也必须声明为抽象类。

(3)抽象类的特征
抽象类的特征总结起来可以说是 有得有失

有得:抽象类得到了拥有抽象方法的能力。

有失:抽象类失去了创建对象的能力。

其他成员(构造方法,实例方法,静态方法等)抽象类都是具备的。
(3)抽象类的细节

  • 1.抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。

理解:假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义。

  • 2.抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。

理解:子类的构造方法中,有默认的super(),需要访问父类构造方法。

8.接口

(1)接口成分的特点

  • 1.抽象方法
    注意:接口中的抽象方法默认会自动加上public abstract修饰程序员无需自己手写!!
    按照规范:以后接口中的抽象方法建议不要写上public abstract。因为没有必要啊,默认会加上。

  • 2.常量
    在接口中定义的成员变量默认会加上: public static final修饰。也就是说在接口中定义的成员变量实际上是一个常量。这里是使用public static final修饰后,变量值就不可被修改,并且是静态化的变量可以直接用接口名访问,所以也叫常量。常量必须要给初始值。常量命名规范建议字母全部大写,多个单词用下划线连接。

  • 3.案例演示

public interface InterF {
    // 抽象方法!
    //    public abstract void run();
    void run();

    //    public abstract String getName();
    String getName();

    //    public abstract int add(int a , int b);
    int add(int a , int b);


    // 它的最终写法是:
    // public static final int AGE = 12 ;
    int AGE  = 12; //常量
    String SCHOOL_NAME = "黑马程序员";

}

(2)接口的实现

/**接口的实现:
    在Java中接口是被实现的,实现接口的类称为实现类。
    实现类的格式:*/
class 类名 implements 接口1,接口2,接口3...{

}

类实现接口的要求和意义:

  • 必须重写实现的全部接口中所有抽象方法。
  • 如果一个类实现了接口,但是没有重写完全部接口的全部抽象方法,这个类也必须定义成抽象类。
  • 意义:接口体现的是一种规范,接口对实现类是一种强制性的约束,要么全部完成接口申明的功能,要么自己也定义成抽象类。这正是一种强制性的规范。

(3)接口的细节

  • 1.当两个接口中存在相同抽象方法的时候,该怎么办?

只要重写一次即可。此时重写的方法,既表示重写1接口的,也表示重写2接口的。

  • 2.如果一个接口中,有10个抽象方法,但是我在实现类中,只需要用其中一个,该怎么办?

可以在接口跟实现类中间,新建一个中间类(适配器类)
让这个适配器类去实现接口,对接口里面的所有的方法做空重写。
让子类继承这个适配器类,想要用到哪个方法,就重写哪个方法。
因为中间类没有什么实际的意义,所以一般会把中间类定义为抽象的,不让外界创建对象

二、常用API

1.Math类

Math类概述:

  • Math是数学工具类,包含执行数学运算的各种方法
  • Math类的构造方法是私有的,无法创建对象,通过类名即可调用方法
public class Demo1 {
    public static void main(String[] args) {
        /*
            public static int        abs(int a)                 获取参数绝对值
            public static double     ceil( double a)            向上取整
            public static double     floor(double a)            向下取整
            public static int        round(float a)             四舍五入
            public static int        max(int a,int b)           获取两个int值中的较大值
            public static double     pow(double a,double b)     返回a的b次幂的值
            public static double     sqrt(double a)             返回a的平方根
            public static double     cbrt( double a)            返回a的立方根
            public static double     random()                   返回值为double的随机值,范围[0.0, 1.0)

         */

        //获取绝对值   Math.absExact();
        double abs = Math.abs(-1.3);
        System.out.println(abs);//1.3

        //向上取整
        System.out.println(Math.ceil(3.13));//4.0
        System.out.println(Math.ceil(-3.14));//-3.0

        //向下取整
        System.out.println(Math.floor(3.14));//3.0
        System.out.println(Math.floor(-3.14));//-4.0

        //四舍五入
        System.out.println(Math.round(3.9));//4
        System.out.println(Math.round(-4.1));//-4

        //获取较大值
        System.out.println(Math.max(123, 138));//138

        //返回a的b次幂的值
        System.out.println(Math.pow(3, 2));//9.0

        //返回a的平方根
        System.out.println(Math.sqrt(4));//2.0

        //返回a的立方根
        System.out.println(Math.cbrt(8));//2.0

        //返回值为double的随机值,范围[0.0, 1.0)
        System.out.println(Math.random());

        System.out.println("-----------------------");

        //创建度数30°
        double a = 30;
        //转变为弧度
        a = Math.toRadians(a);
        System.out.println(Math.sin(a));

    }
}

2.System类

System 类概述:

  • System位于java.lang包下,代表当前Java程序的运行平台。

  • System类中提供了大量静态方法,可以获取与系统相关的信息或执行系统级操作

public class Demo1 {
    public static void main(String[] args) {
        /*
            public static void exit(int status)     终止当前运行的java虚拟机
            public static long currentTimeMillis()  返回当前系统的时间毫秒值形式
            public static void arraycopy(数据源数组,起始索引,目的地数组,起始索引,拷贝个数)    数组拷贝
            细节:
            1.如果数据源和目的地都是基本数据类型,两者类型必须一致,否则会报错
            2.拷贝的时候考虑长度
            3.如果是引用数据类型,那么子类类型可以赋值给父类类型

         */

        //System.exit(0);
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            boolean flag = isPrime2(i);
            if (flag){
                System.out.println(i);
            }
        }
        long end = System.currentTimeMillis();

        System.out.println(end - start);


    }
    public static boolean isPrime1(int num){
        for (int i = 2; i < num ; i++) {
            if (num % i == 0){
                return false;
            }
        }
        return true;
    }
    //效率更高
    public static boolean isPrime2(int num){
        for (int i = 2; i <= Math.sqrt(num) ; i++) {
            if (num % i == 0){
                return false;
            }
        }
        return true;
    }
}

3.RunTime类

public class Demo1 {
    public static void main(String[] args) throws IOException {
        //runtime : 当前虚拟机的运行环境

        /*
        public staticRuntime getRuntime( )      当前系统的运行环境对象
        public void exit(int status)            停止虚拟机
        public int availableProcessors()        获得CPU的线程数
        public long maxMemory( )                JVM能从系统中获取总内存大小(单位byte)
        public long totalMemory ( )             JVM已经从系统中获取总内存大小(单位byte)
        public long freeMemory ( )              JVM剩余内存大小(单位byte)
        public Process exec(string command)     运行cmd命令

         */

        //1.获取runtime的对象
        //Runtime r1 = Runtime.getRuntime();
        //Runtime r2 = Runtime.getRuntime();
        //System.out.println(r1 == r2);//true

        //2.停止虚拟机
        //Runtime.getRuntime().exit(0);

        //3.获取CPU的线程
        System.out.println(Runtime.getRuntime().availableProcessors());//8 线程

        //4.总内存大小
        System.out.println(Runtime.getRuntime().maxMemory()/1024/1024);//4064

        //5.已获取内存大小
        System.out.println(Runtime.getRuntime().totalMemory()/1024/1024);//256

        //6.剩余内存大小
        System.out.println(Runtime.getRuntime().freeMemory()/1024/1024);//253

        //7.运行命令行
        //shutdown : 关机
        //加上参数才能执行
        //-s : 默认在一分钟之后关机
        //-s -t : 指定时间 指定关机时间
        //-a :取消关机操作
        //-r :关机并重启
        Runtime.getRuntime().exec("shutdown -a");
    }
}

4.BigInteger类

构造方法演示:

public class Demo1 {
    public static void main(String[] args) {
        /*
            public BigInteger(int num, Random rnd)      获取随机大整数,范围:[0 ~ 2的num次方-1]
            public BigInteger(String val)               获取指定的大整数
            public BigInteger(String val, int radix)    获取指定进制的大整数

            public static BigInteger valueOf(long val)  静态方法获取BigInteger的对象,内部有优化
         */


        //1.获取随机大整数,范围:[0 ~ 2的num次方-1]
        BigInteger bi1 = new BigInteger(4,new Random());
        System.out.println(bi1);

        //2.获取指定的大整数
        BigInteger bi2 = new BigInteger("9999999999999999999999999999999");
        System.out.println(bi2);

        //3.获取指定进制的大整数   得到的是10进制的数字
        BigInteger bi3 = new BigInteger("11",2);
        System.out.println(bi3);

        //4.静态方法获取BigInteger的对象,内部有优化
        //1.只能在long的取值范围之内,超出long范围不行
        //2.在内部对常用的数字:-16~16进行了优化
        // 提前创建好BigInteger的对象,如果多次创建不会重新创建新的
        BigInteger bi4 = BigInteger.valueOf(16);
        BigInteger bi5 = BigInteger.valueOf(16);
        System.out.println(bi4 == bi5);
    }
}

常用方法演示:

public class Demo2 {
    public static void main(String[] args) {
        /*
            public BigInteger add(BigInteger val)                       加法
            public BigInteger subtract(BigInteger val)                  减法
            public BigInteger multiply(BigInteger val)                  乘法
            public BigInteger divide( BigInteger val)                   除法,获取商
            public BigInteger[] divideAndRemainder(BigInteger val)      除法,获取商和余数
            public boolean equals(object x)                             比较是否相同
            public BigInteger pow(int exponent)                         次幂
            public BigInteger max/ min(BigInteger val)                  返回较大值/较小值
            public int intValue(BigInteger val)                         转为int类型整数,超出范围数据有误

         */
        //创建两个对象
        BigInteger b1 = BigInteger.valueOf(10);
        BigInteger b2 = BigInteger.valueOf(3);

        //1.加法
        BigInteger b3 = b1.add(b2);
        System.out.println(b3);

        //2.除法,获取商和余数
        BigInteger[] b4 = b1.divideAndRemainder(b2);
        System.out.println(b4[0]);//商
        System.out.println(b4[1]);//余数

        //3.比较是否相同,已重写equals方法,比较的内容
        BigInteger b5 = BigInteger.valueOf(10);
        System.out.println(b5.equals(b1));

        //4.次幂
        BigInteger pow = b1.pow(2);// 100的2次方
        System.out.println(pow);//100

        //5.返回较大值/较小值
        BigInteger max = b1.max(b2);
        System.out.println(max);

        //6.转为int类型整数,超出范围数据有误
        int i = b1.intValue();
        long l = b1.longValue();

        System.out.println(i);
        System.out.println(l);

    }
}

5.BigDecimal类

BigDecimal类简介:

  • 因为计算机无法精确表示浮点数,所以在进行数字运算时,如果有double或float类型的浮点数
    参与计算,容易出现计算不准确的情况。

  • 在一些对精度要求很高的系统中,需要使用 BigDecimal 类来进行精确运行。

构造方法演示:

public class Demo1 {
    public static void main(String[] args) {
        /*
            构造方法h获取BigDecimal对象
                public BigDecimal(double val)
                public BigDecimal(String val)
                
            静态方法获取BigDecimal对象
                public static BigDecimal valueOf(double val)
         */

        //1.通过传递double类型的小数创建对象
        //这种方法是不精确的,所以不建议使用
        BigDecimal bd1 = new BigDecimal(0.09);
        System.out.println(bd1);//0.8999999999666933.........不精确

        //2.通过传递字符串表示的小数来创建对象
        BigDecimal bd2 = new BigDecimal("0.09");
        BigDecimal bd3 = new BigDecimal("0.01");
        BigDecimal bd4 = bd2.add(bd3);
        System.out.println(bd2);//0.09
        System.out.println(bd3);//0.01
        System.out.println(bd4);//0.10

        //3.通过静态方法获取
        BigDecimal bd5 = BigDecimal.valueOf(3.1415926);
        System.out.println(bd5);

        //细节:
        //1.如果要表示的数字不大,没有超出double的范围,建议使用静态方法
        //2.如果表示的数字比较大,超出了double的范围,建议使用构造方法
        //3.如果我们传递的是[0,10]之间的整数,会返回已经创建好的对象,不会重新new
        
    }
}

常用方法演示:

public class Demo2 {
    public static void main(String[] args) {
        /*

            public BigDecimal add(BigDecimal val)                            加法
            public BigDecimal subtract(BigDecimal val)                       减法
            public BigDecimal multiply(BigDecimal val)                       乘法
            public BigDecimal divide(BigDecimal val)                         除法
            public BigDecimal divide(BigDecimal val, 精确几位,舍入模式)         除法

         */

        BigDecimal bd1 = new BigDecimal("10.0");
        BigDecimal bd2 = new BigDecimal("4.0");

        //1.加法
        BigDecimal bd3 = bd1.add(bd2);
        System.out.println(bd3);//13.0

        //2.乘法
        BigDecimal bd4 = bd1.multiply(bd2);
        System.out.println(bd4); //30.00

        //3.除法
        BigDecimal bd5 = bd1.divide(bd2,2, RoundingMode.HALF_UP);
        System.out.println(bd5);//3.33
        System.out.println("--------------");


        System.out.println(bd1.divide(bd2, RoundingMode.HALF_UP));
    }
}

6.包装类

(1)为什么有包装类?

  • 基本数据类型有8种.基本数据类型效率高,但是功能及其有限,只能做加减乘除运算.
  • 为了对基本数据类型进行更多的操作,Java为每种基本数据类型提供了对应的类(包装类)
    在这里插入图片描述
    (2)包装类和String相互转换
		//2.基本类型转字符串    
		//包装类的 toString()方法 
		//String类的 valueOf()方法
        int a = 101;
        Integer b = 110;
        String s2 = Integer.toString(a);
        String s3 = String.valueOf(b);

        //3.重点:把字符串转为基本类型   包装类里的 parseXxx方法   parseInt
        String s = "123";
        int i = Integer.parseInt(s);
        System.out.println(i);

        String s1 = "3.1415926";
        double d = Double.parseDouble(s1);
        System.out.println(d);

        //字符串转字符  直接使用String的方法 charAt(索引)
        String str = "A";
        char c = str.charAt(0);
        System.out.println(c);

(3)自动装箱和拆箱

public class Demo1 {
    public static void main(String[] args) {
        int a = 10;
        
        //Integer b = new Integer(100);手动装箱
        
        Integer b = 100;//自动装箱

        //a = b.intValue();手动拆箱

        a = b;//自动拆箱

        System.out.println(a);
    }
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值