Java基础知识总结

Java基础

  1. 封装(通过private对类中属性进行隐藏,通过get、set方法来获取或赋值)
    • 可以提高程序的安全性,保护数据
    • 在方法中可以隐藏代码的实现细节
    • 统一接口、统一规范
    • 增加系统可维护性
  2. 继承(关键字extends。java中所有类都直接或间接的继承了Object类)
    • 子类继承了父类,就会拥有父类所有的方法和属性(除了修饰符是static和private的)(父类属性是私有的private的话,子类无法获取,需要通过get、set)
    • java中只有单继承,没有多继承(一个儿子只能有一个父亲,一个父亲能有多个儿子)
    • 子类调用父类属性或方法可以使用super,但是父类私有private私有东西子类无法调用
    • 子类继承父类,new一个子类的时候,会先调用父类的构造器,子类构造器会有隐藏代码super();如果想显现写出来super();必须放在子类构造器第一行
  3. 多态(同一方法会根据对象的不同,而采取不同的行为方式)
    • 多态是方法的多态,属性没有多态
    • 父类和子类,要有联系,否则类转换异常(ClassCastException(类转换异常))
    • 存在条件:
      • 有继承关系
      • 方法需要重写
      • 父类引用指向子类对象 Father f = new Son();
  4. 重写(需要有继承关系,子类重写父类的方法)
    • 重写都是方法的重写,和属性无关
    • 两个方法名必须相同,参数列表也必须相同
    • 两个方法体不一样
    • 如果方法是static、final、private修饰,则无法被重写
    • A extends B 如果方法是static静态方法,那么方法的调用只和左边定义的数据类型有关B b = new A();调用的会是B类中的方法
    • A extends B 如果方法是非静态方法,B b = new A();相当于子类A重写了父类的方法,调用的会是A类中的方法
    • 子类继承父类,并且和父类方法名字相同,只不过方法的实现不一样,叫做重写,并且方法修饰符必须是public
    • 为什么要用重写? 当父类方法不满足子类,或者子类不一定需要,就需要重写来实现子类自己想需要的东西
    • 扩展
      1. 子类重写父类的方法,修饰符可以扩大但不能缩写 private < default < protected < public
      2. 相反,抛出的异常,范围可以缩小,不能放大
  5. 重载
    • 方法重载:在同一个类中,有相同的方法(函数)名,但是形参不同的函数
    • 方法名称必须相同
    • 参数列表必须不同(参数个数不同,参数类型不同,参数排列顺序不同)
    • 方法的返回类型可以相同,也可以不相同, 仅仅返回类型不同,不足以是方法的重载
  6. Super
    • super调用父类的构造方法,必须super();放在构造方法的第一行
    • super只能出现在子类的方法或者构造方法中
    • super和this不能同时调用构造方法(谁都得放第一行就会报错)
  7. instanceof
    • x instanceof y(判断x是不是属于y类型)
  8. 类型转换(方便方法的调用,减少重复的代码)
    • Father f = new Son();子类转成父类,低转高可直接转(向下转型)
    • Son s = (Son) new Father();父类转成子类,高转低需要强制转换(向上转型)
  9. static
    • 被static修饰过的方法或者属性,可以通过ClassName.param;或者ClassName.method();来直接调用
    • 不仅可以用在属性或者方法上,还可以放到import导入包中(import static java…)
    • 当一个类中同时有static代码块、匿名代码块、无参构造方法代码块(new Class()对象的时候执行顺序为:static > 匿名 > 无参构造方法)
      • static: static{System.out.println(“静态代码块”);}
      • 匿名代码块: {System.out.println(“匿名代码块”);}
      • 构造方法: public ClassName(){System.out.println(“构造方法代码块”);}
    • static是和类一块加载,所以优先执行static的方法,但是只会执行一次,后面再实例化对象不会出发static中的方法
  10. final
    • final修饰过的类不能被继承
    • final修饰过的方法不能被重写
    • final修饰的属性必须有初始化值,并且不可以修改
  11. 抽象类(abstract 约束~)
    • 抽象类中方法靠其他类extends来实现抽象方法,只能单继承
    • 抽象类不可以被new
    • 抽象方法没有方法体,只有名字和类型
    • 抽象类中可以写普通的方法
    • 抽象方法必须在抽象类中
  12. 接口(interface)
    • 定义
      • 接口中方法都是public abstract进行修饰(可以省略不写,只写返回类型、方法名称、参数即可)
      • 接口中属性都是public static final进行修饰(可以省略不写,定义后就是常量,不可修改)
      • 接口和抽象类都不能被实例化,他们根本没有构造方法
      • 类可以实现多个接口,多继承关系 implement xService,yService,zService…
      • 类实现接口必须要重写里面接口中所有定义的方法
    • 作用
      • 约束规范
      • 定义一些方法,由他人实现
      • 解耦可复用,后期维护更方便
  13. 异常体系结构(Throwable)
    Throwable(分为Error和Exception)
    • Error
      • 由java虚拟机jvm生成并抛出,大多数遇到Error与开发代码无关,如内存溢出
      • Error通常是灾难性的致命错误,是程序无法控制和处理的,当出现这种异常时,java虚拟机jvm一般会终止线程
    • Exception(分为运行时异常和非运行时异常)通常情况下是可以被程序处理的,并且程序中要尽可能的去处理这些异常
      • RuntimeException(运行时异常)
        • ArrayIndexOutOfBoundsException(数组下标越界异常)
        • NullPointerException(空指针异常)
        • ArithmeticException(算术异常)
        • MissingResourceException(丢失资源异常)
        • ClassNotFoundException(找不到类异常)
      • 非运行时异常
        • IOException
  14. 处理异常(Ctrl + Alt + T 快捷键生成try catch代码块)
    • try(监控代码区域)
    • catch(捕获代码)
    • finally(善后工作,不管有无异常,都会执行)
    • throw(主动抛出异常,一般用作方法体中 throw new Exception)
    • throws(如果方法体处理不了异常,使用throws抛出异常放到方法上,让调用方去处理 void add() throws Exception{})
  15. 自定义异常
    • 自定义异常MyException需要继承父类总异常 MyException extends Exception
    • 需要toString方法输出自定义异常信息public String toString() { return “MyException:{num接受的值不可以为0!}”; }
    • 方法可能会出现自定义异常,可以做以下处理
      • 1:方法只做出抛出异常throws MyException处理,调用方需要自行try catch进行捕获
      • 2:方法内部自己try catch捕获异常,调用方不做处理,可直接调用方法
  16. 数据类型(分为基本数据类型和引用数据类型)
    • 基本数据类型
      • byte、short、int、char、long、float、double、boolean
    • 引用数据类型
      • String、接口、类
    • 数据类型之间转换
      • 低容量到高容量升序(byte->short->char->int->long->float->double)
      • int i = 128;
      • byte b = (byte) i;(高到低需要强制转换 (类型)变量名 会输出-128)
      • double d = i;(低到高自动转换 会输出128.0)
    • 类型转换注意
      • 1:不能对布尔值进行转换
      • 2:不能把对象转成不相干的类型
      • 3:高容量转低容量的时候,需要强制转换
      • 4:转换的时候可能存在内存溢出,以及精度问题
  17. 变量
    • 声明变量
      • byte num3 = 1;
      • short num2 = 1;
      • int num1 = 1;
      • long num4 = 1L;
      • float num5 = 1F;//小数:浮点数
      • double num6 = 1D;
      • char c = ‘b’;//字符
      • boolean flag = true;//布尔:否
      • boolean flag1 = false;//布尔:否
      • int money = 10_0000_0000;//jdk7特性,数字之间可以用下划线分割,方便看数
      • String name = “xx”;//声明单个变量
      • String name1 = “xx”, name2 = “xx”;//声明多个变量
      • int a = 1, aa = 2;
    • 局部变量和实例变量
      • 局部变量必须声明和初始化值 (一个class中有个方法,方法中有个属性,即局部变量)
      • 实例变量中如果值未被初始化,这个值默认是0或者0.0 或者null,注意:布尔值默认是false;(在class下有个变量,即实例变量)
    • 常量
      • final static type varName = “a”;
      • static final type varName = 1;
      • 常量也必须声明和初始化,修饰符顺序无关,全局使用中不可修改
    • 命名规范
      • 所有变量、类、方法都要:见名知意
      • 类成员变量、局部变量、方法名 要遵循驼峰命名 man goodMan
      • 常量要大写,多词组用下划线分割 final static int NAME_LENGTH = 10;
      • 类名 首字母要大写,并且遵循驼峰命名 Man GoodMan;
  18. 可变参数(通过…声明多个相同类型的变量,多个参数出现…只能放到最后面)
    • public static void manyVariable(int… num){}
    • 调用时
      • manyVariable(new int[]{1, 2, 3});//可以传输数组类型
      • manyVariable(3, 4);//也可以传多个相同类型的数字
  19. 通过cmd编译代码,并运行
    1. 使用cmd命令行需要先编译代码 javac xx.java
    2. 生成xx.class文件
    3. 如果class文件在包下面,需要到src层去执行代码()可以通过命令行来给main方法中args传参
    4. 命令 java com.xx.xx.xx.class -encoding UTF-8 -charset UTF-8 str1 str2 str3
  20. 调用main方法传参给args
    • Class.main(new String[]{“wo”,“ai”,“hwq”});
  21. 运算符
    • 1:算数运算(一元运算、二元运算)
      • { + - * / % ++ --(++ --是自增1和自减-。x++是代码执行完这一行i才会+1,++x是代码运行到这一行x已经-1,-- 同理) }
    • 2:赋值运算
      • int num = 10;
    • 3:关系运算
      • (> ,<, ==, >=, <=, !=)
    • 4:幂运算
      • 幂运算,例如2^3,2的三次方,2³ = 2 * 2 * 2 = 8
      • 很多时候,我们会使用工具类来进行数据操作System.out.println(Math.pow(2, 3));
    • 5:逻辑运算((&&)并且、 (||)或者、 (!)取反)
      • && 两个都为真,结果才是真(判断到第一个比较是假,则直接返回假,也就是直接短路)
      • || 两个有一个真,结果就是真(判断到第一个是真,则直接返回真)
      • ! 如果是真,则为假,如果是假则为真(取反)
    • 6:短路运算
      • 当第一个条件不满足时,&&会直接返回false,后面的不做判断
    • 7:扩展赋值运算(偷懒写法)
      • (+= -= *= /=)a+=b 同 a = a + b;
    • 8:三目运算(条件运算&三元运算)
      • x ? y : z(如果x是true的话,结果为y,否则为z)
      • 实例:int a = 10; String str = a < 12 ? “小于12” : “大于12”; (输出小于12)
    • 9:字符串连接符
      • int a1 = 10,b1 = 20;
        • System.out.println(“”+a1+b1);//输出1020 String在前面,后面的开始拼接字符
        • System.out.println(a1+b1+“”);//输出30 String在最后面,前面的开始计算,不拼接
        • System.out.println(a1+“”+b1);//输出1020 String在中间,也是拼接
  22. 递归(可以用简单的程序来解决复杂的方法,大大减少了代码量,它的能力在于用有限的语句来定义对象无限的集合)
    • 递归头:处理什么时候不调用自身方法,如果没有头,将会陷入死循环
    • 递归体:什么时候需要调用自身方法
    • 例子:计算阶乘(5! = 5 * 4 * 3 * 2 * 1)
public class Recursion {
    /**
     * 计算阶乘
     * 1! 1
     * 2! 2 * 1
     * 3! 3 * 2 * 1
     * ...
     * 5! 5 * 4 * 3 * 2 * 1
     */
    public static int factorial(int num) {
        if (num == 1) {
            return 1;
        } else {
            return num * factorial(num - 1);
        }
    }
    public static void main(String[] args) {
        System.out.println(factorial(5));
    }
}
  1. while和dowhile(while是先判断再执行,dowhile是先执行后判断,所以dowhile最少会执行一次)
    //while
    public static void testWhile() {
        int i = 1;
        int sum = 0;
        while (i <= 100) {
            sum += i;
            i++;
        }
        System.out.println(sum);
    }
    //dowhile
    public static void testDoWhile(){
        int i = 0;
        int sum = 0;
        do {
            sum+=i;
            i++;
        }while (i<=100);
        System.out.println(sum);
    }
  1. 数组[]
    • 定义数组
      • int[] a = {1, 1, 1}; int[] c = new int[]{1, 2, 3}; //静态初始化(声明即赋值)
      • int[] b = new int[5]; b[0] = 1; //动态初始化(包含默认初始化,int类型不赋值默认为0,String类型默认为null…)
    • 数组特点
      • 1:长度是确定的,数组一旦被创建,它的大小就不可以被改变了
      • 2:元素必须是相同类型,统一的,不能出现其他元素类型
      • 3:数组类型可以是任意数据类型,包括基本类型和引用类型
      • 4:数组变量属于引用类型,数组也可以看成是对象,数组中的每个元素相当于对象中的成员变量
      • Java中对象是存在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的
    • Arrays工具类的简单使用
      • int[] a = {1,5,3,4,7,5,6,9};
      • System.out.println(Arrays.toString(a));//输出a数组
      • Arrays.sort(a);//给数组排序(升序)
      • Arrays.fill(a,0);//给数组填充值(下面将所有数组中元素变成0)
      • Arrays.fill(a,2,5,0);//指定元素下标起点和重点index填充0(前包后不包,下标为2,3,4的会变成0)
    //冒泡排序
    public static int[] bubbleSort(int[] array) {
        //临时变量
        int temp;
        //外层循环,遍历每个元素
        for (int i = 0; i < array.length - 1; i++) {
            //内层循环,开始比较相邻元素,将最大值放到最前
            for (int j = 0; j < array.length - 1 - i; j++) {
                if (array[j + 1] > array[j]) {
                    //相比较后大的值先放到临时变量中
                    temp = array[j + 1];
                    //较小的值将放到j+1后一位元素中
                    array[j + 1] = array[j];
                    //最后较大的值放入j的位置,到此两个数比较大小后,位置也发生完变化
                    array[j] = temp;
                }
            }
        }
        return array;
    }
    //反转数组
    static int[] nums = {1, 2, 4, 3};

    public static void reverseNums() {
        int[] reverseNums = new int[nums.length];
        // 方法1
        int k = 0;
        for (int i = nums.length - 1; i >= 0; i--) {
            reverseNums[k] = nums[i];
            k++;
        }
        //方法2
        for (int i = nums.length - 1, j = 0; i >= 0; i--, j++) {
            reverseNums[j] = nums[i];
        }
        if (reverseNums.length != 0) {
            System.out.print("反转数组后值为:");
            for (int reverseNum : reverseNums) {
                System.out.print(reverseNum + "\t");
            }
        }
    }
    //二维数组
    public static void main(String[] args) {
        //定义二维数组
        int[][] twoDimensionArray = new int[1][5];
        //赋值
        twoDimensionArray[0][1] = 1;
        twoDimensionArray[0][2] = 2;

        //直接声明二维数组
        int[][] twoDimensionArray1 = {{1, 2, 3}, {1, 2, 3}, {3}};

        for (int i = 0; i < twoDimensionArray1.length; i++) {
            System.out.print("\n");
            System.out.print("二维数组中第" + i + "个中的元素值为:");
            for (int j = 0; j < twoDimensionArray1[i].length; j++) {
                System.out.print(twoDimensionArray1[i][j] + "\t");
            }
        }
    }
  1. 构造器(public ClassName(){})
      1. 和类方法名相同
      1. 没有返回值
    • 使用new关键字的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化值,以及对类中的构造器进行调用(有参无参数构造方法),这些调用完才会new出来对象
    • 使用new关键字,本质就是在调用构造器,用来初始化值
    • 一个class即使什么都不写,也会存在一个无参构造方法
    • 作用:
      • new的本质就是在调用构造器
      • 初始化对象的值
    • 注意点:
      • 定义了有参构造的时候,如果想调用无参构造,那么类中必须定义一个无参构造方法,否则报错
  2. for循环
    • for (int i = 0; i <= 100; i++){}
    • break; 终止循环
    • continue; 跳出本次循环
    //break; 终止循环,会输出到19,20 == 20 break会终止循环
    for (int i = 0; i < 100; i++) {
        System.out.println(i);
        if (i == 20) {
           break;
        }
    }
    System.out.println("遇到20刺客,我们已经撤退!");
    
    
    //continue; 跳出本次循环,会输出0-30能整除3的数
    for (int j = 0; j < 30; j++) {
        if(j%3==0){
           System.out.println("能干干净净吃掉3的,咱也不要!");
           continue;
        }
        System.out.println(j);
    }
    //死循环
    for (; ; ) {
    //计算0-100之间奇数和偶数的和
    public static void zeroToOneHundredOddEvenSum() {
        int oddSum = 0;
        int evenSum = 0;
        for (int i = 0; i <= 100; i++) {
            //i余(模)2 = 0,代表偶数
            if (i % 2 == 0) {
                oddSum += i;
            } else {
                evenSum += i;
            }
        }
        System.out.println("奇数和为:" + oddSum + "偶数和为:" + evenSum);
    }

    //找出0-1000能被5除的整数,并且每行输出三个
    public static void zeroToKiloDivideFive() {
        for (int i = 1; i <= 1000; i++) {
            if (i % 5 == 0) {
                System.out.print(i + "\t");
            }
            if (i % (5 * 3) == 0) {
                System.out.println();
            }
        }
    }

    //99乘法表
    public static void nineMultiplyNine() {
        for (int i = 1; i <= 9; i++) {
            for (int j = 1; j <= i; j++) {
                System.out.print(i + "*" + j + "=" + i * j + "\t");
            }
            System.out.println();
        }
    }
    //打印三角形
    public static void printTriangle() {
        int n = 5; // 定义一个整型变量n,表示三角形的高度
        for (int i = 1; i <= n; i++) { // 外层循环控制行数,从第一行开始到第n行结束
            for (int j = 1; j <= n - i; j++) { // 内层循环控制每行的空格数,从第一行开始到第n-i行结束
                System.out.print(" "); // 输出一个空格
            }
            for (int k = 1; k <= 2 * i - 1; k++) { // 内层循环控制每行的星号数,从第一行开始到第2*i-1行结束(1,3,5,7,9 规律2*i-)
                System.out.print("❤"); // 输出一个星号
            }
            System.out.println(); // 换行,进入下一行的输出
        }
    }
    //高阶语法使用
    int[] num = {10, 20, 30, 40, 50};
    for (int i : num) {
        System.out.println(i);
    }
  1. 值传递
    • 在Java中,传递方式只有一种,那就是值传递。
      • 当我们传递基本数据类型(如int、float、boolean等)时,会复制一个新的值。
      • 如果我们在方法中修改了这个值,那么原始的值并不会改变。这就是值传递的基本概念。
      • 而当我们传递对象引用时,虽然引用本身的值(即内存地址)并没有被改变,但是通过这个引用我们可以修改对象的状态。
      • 这就是因为Java中的对象是通过引用传递的。换句话说,传递的是对象的引用,而不是对象本身。
/**
 * 值传递
 * 在Java中,基本数据类型(如int、float、double)是按值传递的,而不是按引用传递的。
 * 当将一个变量的值传递给一个方法时,该方法会创建一个新的变量(在这个例子中是num),该变量的值与原始变量的值相同。
 * 所以,在change方法中更改num的值时,只是更改了传递给方法的num的副本的值,而原始的num变量的值并没有改变。
 */
public class ValueTransmit {
    public static void main(String[] args) {

        int num = 1;
        System.out.println(num);//输出1

        change(num);
        System.out.println(num);//输出1

        String str = "en";
        changeStr(str);
        System.out.println(str);//输出en
    }

    public static void change(int num) {
        num = 10;
    }

    public static void changeStr(String str){
        str = "enen";
    }
}
/**
 * 引用传递:对象,本质还是值传递
 */
public class CiteTransmit {
    public static void changeName(Person person){
        //现在person是一个对象,指向的Person person = new Person();这是一个具体的人,所以可以改变属性值
        person.name = "lxxxxx";
    }

    public static void main(String[] args) {
        Person person = new Person();
        person.name = "lx";
        System.out.println(person.name);//输出lx
        changeName(person);
        System.out.println(person.name);//输出lxxxxx
    }
}

class Person {
    String name;
}
  • 36
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值