Java基础知识(一)

Java基础知识(一)

参考文档:https://docs.oracle.com/en/java/javase/17/docs/api/index.html

一、数组

1、 一维数组

数组:可以用来存储同种数据类型的多个值

  • int类型数组可以包含byte、short、int
  • double数组可以包含byte、short、int、long、float、double

定义:

  • 数据类型[] 数组名
  • 数据类型 数组名[]
package TestCode;

public class TestClass {
    public static void main(String[] args) {
        int[] arr1 = new int[2];
        arr1[0] = 11;
        arr1[1] = 22;

        int[] arr2 = {33, 44, 55};

        int[] arr3 = arr2;
    }
}

图片.png

2、 二维数组

package TestCode;

public class TestClass {
    public static void main(String[] args) {
        int[][] arr = new int[2][3];
    }
}

图片.png

package TestCode;

public class TestClass {
    public static void main(String[] args) {
        int[][] arr = new int[2][];
        int[] arr1 = {11, 22};
        int[] arr2 = {44, 55, 66};
        
        arr[0] = arr1;
        arr[1] = arr2;
    }
}

图片.png

3、 Arrays

二分查找法查找元素:public static int binarySearch(数组,查找元素)

  • 前提数组中的元素必须是有序的且是升序
  • 如果查找元素存在返回真实的索引,否则返回插入点(查找元素应该在的位置)-1

拷贝数组:public static int[] copyOf(原数组, 新数组长度)

  • 根据第二个参数创建新数组
    • 如果新数组长度小于原数组,部份拷贝
    • 如果新数组长度等于原数组,完全拷贝
    • 如果新数组长度大于原数组,补上默认初始值

数组排序:public static void sort(数组)

  • 默认升序,底层是快速排序(以下代码是降序)
package TestCode;

import java.util.Arrays;
import java.util.Comparator;

public class TestClass {
    public static void main(String[] args) {
        /*
            public static void sort(数组,排序规则)
            参数一:要排序的数组
            参数二:排序的规则
            细节:
                只能给引用数据类型的数组进行排序
                如果数组是基本数据类型的,需要变成其对应的包装类
        */
        Integer[] arr = {2, 3, 1, 5, 6, 7, 8, 4, 9};

        //第二个参数是一个接口,所以在调用方法时需要传递这个接口的实现类对象,作为排序规则
        //这个实现类只需使用一次,所以采取匿名内部类的方式就可以

        /*
            底层原理:
            利用插入排序和二分查找的方式进行排序的
            默认把0索引的数据当作是有序的序列,1索引到最后认为是无序的序列
            遍历无序的序列得到里面的每一个元素,假设当前遍历得到的元素是A元素
            把A往有序序列中进行插入,在插入的时候利用二分查找确定A的元素插入点。
            拿着A元素和插入点元素进行比较,比较的规则就是compare方法的方法体
            如果方法的返回值是负数,A继续和前面的数据进行比较
            如果方法的返回值是正数,A继续和后面的数据进行比较
            如果方法的返回值是0,A继续和后面的数据进行比较
            直到确定A的最终位置为止
        */


        /*
            compare方法的形参:
            参数一 o1:表示在无序的序列中遍历得到的每一个元素
            参数二 o2:表示有序序列中的元素

            返回值:
            负数:表示当前要插入的元素是小的,放在前面
            正数:表示当前要插入的元素是大的,放在后面
            0:表示当前要插入的元素和现在的元素比是一样的 会放在后面
         */

        //o1 - o2 升序排列
        //o2 - o1 降序排列

        //匿名内部类
        /*Arrays.sort(arr, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });*/
        
        //lambda表达式
        /*Arrays.sort(arr, (Integer o1, Integer o2) -> {
            return o2 - o1;
        });*/
        Arrays.sort(arr, (o1,  o2) -> o2 - o1);

        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}

二、面向对象

1、类和对象

JavaBean类:用来描述一类事物的类,不写main方法
测试类:编写main方法的类,可以在测试类创建JavaBean类的对象赋值调用
注:一个java文件中可以定义多个类,但只能一个类是public修饰,且这个类名必须和文件名一致,建议一个文件定义一个类

标准的JavaBean类:

  1. 类名大驼峰
  2. 成员变量用private修饰
  3. 提供至少两个构造方法
    1. 无参
    2. 带全部参数
  4. 成员方法
    1. 每个成员变量对应的set和get方法
package TestCode;

public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

2、封装(private)

  • private关键字是一个权限修饰符
  • 可以修饰成员变量和成员方法
  • 被private修饰只能在本类中访问
  • 使用setXxx()方法给成员变量赋值,public修饰
  • getXxx()方法获取成员变量的值,public修饰

3、构造方法

构造器、构造函数:在创建对象的时候给成员变量进行赋值
特点:

  • 方法名与类名完全一致
  • 没有返回值类型,也不需要void
  • 没有返回值,不需要return

执行:

  • 创建对象的时候虚拟机调用,每创建一次就调用一次

注意:

  • 构造方法没有被定义,系统会提供默认的无参构造,定义了就不再提供
  • 构造方法重载:方法名相同 但参数个数不同

4、内存图

  1. 加载class文件
  2. 申明局部变量
  3. 在堆内存中开辟一个空间
  4. 默认初始化 或 显式初始化
  5. 构造方法初始化
  6. 将堆内存中的地址值赋值给局部变量
package TestCode;

public class Student {
    //name没有被赋值,需要默认初始化
    String name;
    //age被赋值,是显示初始化
    int age = 23;

    public void test()
    {
        System.out.println("test");
    }
}

package TestCode;

public class TestClass {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.name = "zhangsan";
        s1.age = 25;
        s1.test();

        Student s2 = new Student();
        s2.name = "lisi";
        s2.age = 26;
        s2.test();
        
        Student s3 = s2;
    }
}

图片.png

5、this

作用:区分局部变量和成员变量
本质:代表方法调用者的地址值

package TestCode;

public class Student {
    private int age;
    public void method(){
        int age = 10;
        System.out.println(age);
        System.out.println(this.age);
    }
}

package TestCode;

public class TestClass {
    public static void main(String[] args) {
        Student s = new Student();
        s.method();
    }
}

图片.png

6、成员变量和局部变量

区别成员变量局部变量
类中位置类中,方法外方法内
初始化位置有默认初始化值没有,使用前需要赋值
内存位置堆内存栈内存
生命周期跟随对象跟随方法
作用域整个类方法中

7、static

static表示静态,可以修饰成员变量和成员方法
注意:

  • 静态方法中只能访问静态变量和静态方法
  • 非静态方法可以访问所有
  • 静态方法中没有this关键字

静态变量

特点:

  • 被该类所有对象共享
  • 不属于对象,属于类
  • 随着类的加载而加载,优先于对象

调用方式:

  • 类名调用(推荐)
  • 对象名调用

静态方法

特点:

  • 多在测试类和工具类中使用(工具类:私有化构造方法且方法定义为静态)
  • JavaBean类中很少会用

调用方式:

  • 类名调用(推荐)
  • 对象名调用
package TestCode;

public class Student {
    String name;
    int age;
    static String teacherName;

    public static void method(){
        System.out.println("静态方法");
    }

    public void show(){
        System.out.println(this.name + " " + this.age + " " + teacherName);
    }

}
package TestCode;

public class TestClass {
    public static void main(String[] args) {
        Student.teacherName = "李老师";
        Student.method();
        Student s1= new Student();
        s1.name = "zhangsan";
        s1.age = 23;
        s1.show();

        Student s2= new Student();
        s2.show();
    }
}

图片.png

8、继承

子类 extends 父类
特点:

  • 只支持单继承,不支持多继承,但支持多层继承
  • 所有类都直接或间接继承Object
  • 子类只能访问父类的非私有成员
  • 只有父类中非private非static非final成员方法才会被继承
  • 成员变量访问采用就近原则,局部 -> 本类成员 -> 父类成员
  • 父类构造方法不会被子类继承,子类所有的构造方法默认先访问父类中无参构造再执行自己

重写:

  • @Override重写注解
  • 形参列表必须与父类一致
  • 访问权限子类必须大于等于父类
  • 返回值类型子类必须小于等于父类
  • 非private非static非final方法才能被重写

图片.png

9、多态

父类类型 对象名称 = 子类对象;
前提:

  • 有继承关系
  • 有父类引用指向子类对象
  • 有方法重写

特点:

  • 方法中使用父类型作为参数,可以接收所有子类对象
  • 不能使用子类的特有功能,但可以类型转换成子类类型,从而调用子类独有功能
  • 转换时用instanceof关键字进行判断防止转化类型与真实对象类型不一致报错
package TestCode;

public class Person {
    String name = "All";

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    public void show(){
        System.out.println("全部人员:" + this.name);
    }
}

package TestCode;

public class Admin extends Person{
    String name = "Admin";

    public Admin() {
        super();
    }

    @Override
    public void show(){
        System.out.println("管理员:" + this.name);
    }

}

package TestCode;

public class Teacher extends Person{
    String name = "Teacher";

    public Teacher() {
        super();
    }

    @Override
    public void show(){
        System.out.println("老师:" + this.name);
    }

}

package TestCode;

public class Student extends Person{
    String name = "Student";

    public Student() {
        super();
    }

    @Override
    public void show(){
        System.out.println("学生:" + this.name);
    }

}

package TestCode;

public class TestClass {
    public static void main(String[] args) {
        /*Person p = new Teacher();
        if (p instanceof Admin){
            Admin admin = (Admin) p;
            admin.show();
        }else if (p instanceof Teacher){
            Teacher teacher = (Teacher) p;
            teacher.show();
        }else if (p instanceof Student){
            Student student = (Student) p;
            student.show();
        }*/
        Person p = new Teacher();
        if (p instanceof Admin admin){
            admin.show();
        }else if (p instanceof Teacher teacher){
            teacher.show();
        }else if (p instanceof Student student){
            student.show();
        }


    }
}

10、包和final

:用来管理不同功能Java类的文件夹
规则:

  • 公司域名反写 + 包作用,全部小写
  • 使用同一个包中的类不需要导包
  • java.lang类不需要导包
  • 其他都需要导包
  • 同时使用两个包中的同名类,需要用全类名
final

final

  • 修饰类:最终类,不能被继承
  • 修饰方法:最终方法,不能被重写
  • 修饰变量:叫做常量 只能被赋值一次
    • 基本类型:数据值不能发生改变
    • 引用类型:地址值不能发生改变,内部能发生改变

11、权限修饰符和代码块

修饰符
修饰符同一个类中同一个包其他类不同包下的子类不同包下的无关类
private
protected
public
代码块

构造代码块:

  • 写在成员位置
  • 可以将构造方法中重复代码抽取出来
  • 创建本类对象时先执行构造代码块再执行构造方法

静态代码块:

  • static{}
  • 随着类的加载而加载,自动触发并只执行一次
  • 类加载时做一些数据初始化使用

12、抽象类和抽象方法

抽象方法:
将共性的行为 (方法)抽取到父类之后。由于每一个子类执行的内容是不一样所以,在父类中不能确定具体的方法体该方法就可以定义为抽象方法。
抽象类:
如果一个类中存在抽象方法,那么该类就必须声明为抽象类

抽象方法的定义格式:
public abstract 返回值类型 方法名(参数列表);
抽象类的定义格式:
public abstract class 类名{}

特点:

  • 抽象类象不能实例化
  • 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
  • 可以有构造方法 (作用 :当创建子类对象时,给属性进行赋值)
  • 抽象类的子类 要么重写抽象类中的所有抽象方法、要么是抽象类

13、接口

接口是一种规则,对行为的抽象

接口的定义和使用

  • 接口用关键字interface来定义
    public interface 接口名{}

  • 接口不能实例化

  • 接口和类之间是实现关系,通过implements关键字表示

    • public class 类名 implements 接口名{}
  • 接口的子类(实现类)

    • 要么重写接口中的所有抽象方法
    • 要么是抽象类

:::tips
注意1: 接口和类的实现关系,可以单实现,也可以多实现。
public class 类名 implements 接口名1,接口名2 {}
注意2:实现类还可以在继承一个类的同时实现多个接口。
public class 类名 extends 父类 implements 接口名1,接口名2 {}
:::

接口中成员的特点
  • 成员变量只能是常量 —— 默认修饰符: public static final
  • 没有构造方法
  • 成员方法
    • 默认修饰符: public abstract

    • JDK7以前: 接口中只能定义抽象方法

    • JDK8的新特性:接口中可以定义有方法体的方法 - 不用重写也可以被调用

      • 接口中默认方法的定义格式:

        • 格式: public default 返回值类型 方法名(参数列表)
        • 范例: public default void show(){}
      • 接口中默认方法的注意事项

        • 默认方法不是抽象方法,所以不强制被重写。但是如果被重写,重写的时候去掉default关键字
        • public可以省略,default不能省略
        • 如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写
    • JDK8的新特性:接口中可以定义静态方法。 —— 不能被重写

      • 接口中静态方法的定义格式:

        • 格式:public static 返回值类型 方法名(参数列表) {}
        • 范例: public static void show() {}
      • 接口中静态方法的注意事项

        • 静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
        • public可以省略static不能省略
    • JDK9的新特性:接口中可以定义私有方法 —— 抽取默认和静态方法的重复代码并不允许被其他使用

      • 格式1:private 返回值类型 方法名(参数列表){}

      • 范例1: private void show(){}

      • 格式2:private static 返回值类型方法名(参数列表){}

      • 范例2: private static void method(){}

14、内部类

图片.png

  • 内部类可以直接访问外部类的成员包括私有
  • 外部类访问内部类成员必须创建对象
成员内部类
  • 在成员位置,属于外部类成员
  • 可以被修饰符修饰
  • JDK16之后可以定义静态变量
  • 获取内部类对象方式
    • 在外部类中编写方法,对外提供内部类对象
    • 直接创建:外部类名.内部类名 对象名 = 外部类对象.内部类对象;
package TestCode;

public class Outer {
    private int a = 10;

    class Inner{
        private int a = 20;
        public void show(){
            int a = 30;
            System.out.println(a);
            System.out.println(this.a);
            System.out.println(Outer.this.a);
        }
    }

}

package TestCode;

public class TestClass {
    public static void main(String[] args) {
        Outer.Inner inner = new Outer().new Inner();
        inner.show();
    }
}

图片.png

package TestCode;

public class Outer {
    private int a = 10;

    class Inner{
        private int a = 20;
        public void show(){
            int a = 30;
            System.out.println(a);
            System.out.println(this.a);
            System.out.println(Outer.this.a);
        }
    }

    public Inner getInstance(){
        return new Inner();
    }

}

package TestCode;

public class TestClass {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.getInstance().show();
    }
}
静态内部类
  • 静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态需创建对象。
  • 创建静态内部类对象:外部类名.内部类名 对象名 = new 外部类名.内部类名();
  • 调用静态方法:外部类名.内部类名.方法名();
package TestCode;

public class Outer {
    static class Inner{
        public void show1(){
            System.out.println("非静态方法");
        }
        public static void  show2(){
            System.out.println("静态方法");
        }
    }

}

package TestCode;

public class TestClass {
    public static void main(String[] args) {
        Outer.Inner inner = new Outer.Inner();
        inner.show1();

        Outer.Inner.show2();
    }
}
局部内部类
  • 局部内部类:将内部类定义在方法里
  • 外界无法使用,需要在方法里创建对象才可使用
  • 可直接访问外部类的成员也可访问方法内的局部变量
匿名内部类
  • 包含了继承或实现、方法重写、创建对象,即是一个类的子类对象或接口的实现类对象。

  • 使用场景:如果实现类只使用一次就可以用匿名内部类

  • 格式:

    new 类名或者接口名(){
    	重写方法;
    };
    
package TestCode;

public abstract class Father {
    int num;
    public abstract void method();
}

package TestCode;

public class Outer {
    public void show(){
        //匿名内部类所产生的对象,一定不是new的类型的对象(因为是抽象类),而是new类型的子类对象!
        Father father = new Father() {
            @Override
            public void method() {
                System.out.println("匿名内部类");
            }
        };
        father.method();
    }


}

package TestCode;

public class TestClass {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.show();
    }
}

注:
参考视频:
https://www.bilibili.com/video/BV17F411T7Ao?p=1&vd_source=a89593e8d33b31a56b894ca9cad33d33
https://www.bilibili.com/video/BV1yW4y1Y7Ms?p=1&vd_source=a89593e8d33b31a56b894ca9cad33d33

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值