当前位置: 首页 > news >正文

Java 核心知识点查漏补缺(一)

Java 核心概念补充说明

一、封装的实际意义与示例解析

封装是面向对象三大特性之一,核心是通过访问权限控制隐藏类的内部实现细节,仅暴露必要的接口供外部交互。

以Person.java为例:

  • name属性用private修饰,限制了直接访问(如person.name = "xiaoming"会报错)
  • 通过public修饰的getName()setName()方法提供访问入口,可在方法中添加验证逻辑(如姓名长度限制)
  • 优势:保护数据完整性、降低代码耦合度、便于后续维护扩展

二、接口的应用场景与特性

接口是一种行为规范,用于定义类必须实现的方法,不关注具体实现。

从Flyable.java和Bird.java看接口特性:

  1. 抽象方法:如fly(),实现类必须重写(Bird类实现了fly()方法)
  2. 默认方法:带default关键字,有默认实现,实现类可选择重写(Bird重写了land()方法)
  3. 静态方法:带static关键字,属于接口本身,通过接口名直接调用(Flyable.info()
  4. 多实现特性:类可同时实现多个接口,弥补 Java 单继承的局限性

接口降低耦合度的体现:当需要新增 "飞行" 功能的类(如Plane)时,只需实现Flyable接口,无需修改原有代码。

三、抽象类与接口的区别

Animal抽象类和Flyable接口对比:

特性抽象类接口
关键字abstract classinterface
实例化不能不能
方法类型可包含抽象方法和具体方法JDK8 + 可包含抽象方法、默认方法、静态方法
继承 / 实现单继承(extends多实现(implements
成员变量可包含各种权限的变量只能是public static final常量
设计意图体现 "is-a" 关系(如Dog is a Animal体现 "has-a" 能力(如Bird has a Flyable能力)

四、内部类的特性与使用场景

以Outer.java中的成员内部类为例:

  1. 访问权限:内部类可直接访问外部类的所有成员(包括private修饰的outerVar
  2. 创建方式
    • 外部类内部:直接new Inner()
    • 外部类外部:需通过外部类实例创建(outer.new Inner()
  3. 应用场景
    • 当内部类仅服务于外部类时,可隐藏实现细节
    • 方便访问外部类的成员,适合编写事件监听器等场景

五、==equals()的深层对比

结合Test01.java中的示例:

  1. 基本数据类型==比较值(如a == c中 10 与 10.0 值相等,返回 true)
  2. 引用数据类型
    • ==比较内存地址(s1 == s2为 false,因是两个不同对象)
    • equals()默认等同于==(Object 类实现),但可重写用于内容比较(如 String 类重写后比较字符序列)
  3. 注意点
    • 比较字符串内容时应使用equals(),而非==
    • 重写equals()时需遵循对称性、传递性等规则,通常需同时重写hashCode()

六、静态成员的特性与生命周期

从Test01.java的Student类示例:

  1. 静态变量static String school):
    • 属于类本身,所有对象共享同一份内存
    • 一个对象修改后,所有对象访问到的都是修改后的值
  2. 静态方法static void eat()):
    • 通过类名直接调用(Student.eat()),无需创建对象
    • 不能访问非静态成员(因静态成员加载时非静态成员可能尚未初始化)
  3. 静态代码块
    • 类加载时执行,且只执行一次
    • 用于初始化静态资源,执行顺序早于构造器

七、多态的实现与优势

在Test02.java中体现:

  1. 向上转型Animal dog = new Dog("旺财")
    • 父类引用指向子类对象,自动完成
    • 可调用父类声明的方法,实际执行子类重写的实现(如dog.eat()执行Dog类的eat()
  2. 优势
    • 提高代码灵活性:同一方法调用可表现不同行为
    • 便于扩展:新增子类(如Cat)无需修改使用父类的代码
  3. instanceof运算符:判断对象实际类型,避免转型错误(如animal instanceof Dog

八、权限修饰符的实际应用

根据Test01.java中的权限表:

  • private:仅本类可见,用于隐藏内部状态(如Personname
  • default(缺省):同一包内可见,适合包内组件间协作
  • protected:同一包或不同包子类可见,用于继承体系中的成员共享
  • public:全局可见,用于对外提供的接口方法(如PersongetName()

合理使用权限修饰符可降低类之间的依赖,提高代码安全性和可维护性。

整理在一起,写成word文档形式

Java 核心知识点全解析

一、数据类型与类型转换

(一)数据类型分类

Java 数据类型分为基本数据类型和引用数据类型,二者在存储方式和使用场景上有显著区别。

  1. 基本数据类型(8 种):直接存储数据值,占用固定内存空间。
    • 整数类型:byte(1 字节)、short(2 字节)、int(4 字节)、long(8 字节),用于存储整数数值,根据数值范围选择对应类型。
    • 浮点类型:float(4 字节)、double(8 字节),用于存储小数,double精度高于float,日常开发中更常用。
    • 字符类型:char(2 字节),用于存储单个字符,如'a''中'
    • 布尔类型:boolean,仅表示true(真)或false(假),JVM 未明确规定其占用内存大小。
  2. 引用数据类型:存储对象的内存地址,而非数据本身,包括类、接口、数组三类。

(二)类型转换规则

类型转换需遵循 “范围匹配” 原则,避免数据精度丢失或运行错误。

  1. 自动转换:小范围类型向大范围类型转换,无需显式声明,数据不会丢失。
    • 转换顺序:byte→short→int→long→float→double
    • 示例:int a = 10; long b = a;aint类型自动转换为long类型。
  2. 强制转换:大范围类型向小范围类型转换,需显式添加目标类型括号,可能导致数据精度丢失。
    • 示例:int c = 100; byte d = (byte)c;,若c值超过byte范围(-128~127),转换后数据会异常。

二、运算符

运算符是用于执行数据运算的符号,Java 提供多种运算符以满足不同计算需求。

  1. 算术运算符:用于基本数学运算,包括+(加)、-(减)、*(乘)、/(除)、%(取余)、++(自增)、--(自减)。
    • 自增 / 自减分为前缀和后缀两种形式:
      • 前缀:++a--a,先执行自增 / 自减,再参与其他运算。
      • 后缀:a++a--,先参与其他运算,再执行自增 / 自减。
    • 示例:int a = 5; int b = a++;b值为 5,a值变为 6);int c = ++a;a值变为 7,c值为 7)。
  2. 赋值运算符:用于给变量赋值,基础运算符为=,扩展运算符包括+=-=*=/=等,可简化代码并自动处理类型转换。
    • 示例:int a = 3; a += 2;(等价于a = (int)(a + 2)a值变为 5)。
  3. 比较运算符:用于比较两个值的关系,结果为boolean类型(truefalse),包括>(大于)、<(小于)、>=(大于等于)、<=(小于等于)、==(等于)、!=(不等于)。
    • 示例:int a = 5, b = 3; System.out.println(a > b);(输出true)。
  4. 逻辑运算符:用于连接布尔表达式,结果为boolean类型,包括&&(短路与)、||(短路或)、!(非)、&(与)、|(或)、^(异或)。
    • “短路” 特性:&&若左侧表达式为false,右侧不再执行;||若左侧表达式为true,右侧不再执行。
    • 示例:int a = 2; System.out.println(a > 3 && ++a > 2);(左侧为falsea值仍为 2)。
  5. 位运算符:直接对二进制位进行运算,包括&(按位与)、|(按位或)、^(按位异或)、~(按位取反)、<<(左移)、>>(右移),常用于底层开发或高效运算。
    • 示例:int a = 3; int b = a << 1;3二进制为11,左移 1 位后为110b值为 6)。
  6. 三元运算符:语法为条件表达式 ? 表达式1 : 表达式2,根据条件表达式结果选择执行表达式 1 或表达式 2,可简化简单的分支逻辑。
    • 示例:int max = (a > b) ? a : b;(若a > bmaxa值,否则取b值)。

三、流程控制

流程控制用于控制代码的执行顺序,包括分支结构和循环结构两类。

(一)分支结构

根据条件判断执行不同代码块,主要有if-elseswitch两种形式。

  1. if-else:适合范围性条件判断,可嵌套使用,逻辑清晰。
    • 语法:

    if (条件1) {// 条件1为true时执行
    } else if (条件2) {// 条件1为false、条件2为true时执行
    } else {// 所有条件均为false时执行
    }
    
    • 示例:
    int score = 85;
    if (score > 90) {System.out.println("优秀");
    } else if (score > 60) {System.out.println("及格");
    } else {System.out.println("不及格");
    }
    
  2. switch:适合等值条件判断,JDK7 及以上支持String类型,需注意 “穿透” 问题。
    • 语法:

    switch (表达式) {case 值1:// 表达式等于值1时执行break; // 终止switch,避免穿透case 值2:// 表达式等于值2时执行break;default:// 表达式不等于任何case值时执行
    }
    
    • 示例:

    String day = "周一";
    switch (day) {case "周一":System.out.println("工作日第一天");break;case "周日":System.out.println("休息日");break;default:System.out.println("普通日期");
    }
    
    • 注意:若省略break,会从匹配的case开始,依次执行后续所有代码,直至遇到breakswitch结束,即 “switch 穿透”。

(二)循环结构

用于重复执行某段代码,主要有forwhiledo-while三种形式。

  1. for:适合已知循环次数的场景,语法简洁,控制变量作用域明确。
    • 语法:

    for (初始化语句; 循环条件; 更新语句) {// 循环体:条件为true时执行
    }
    
    • 示例:
    for (int i = 0; i < 5; i++) {System.out.println("循环第" + (i + 1) + "次");
    }
    
  2. while:适合未知循环次数的场景,先判断条件,再执行循环体。
    • 语法:

    while (循环条件) {// 循环体:条件为true时执行
    }
    
    • 示例:

    int count = 0;
    while (count < 3) {System.out.println("count: " + count);count++;
    }
    
  3. do-while:与while类似,但先执行一次循环体,再判断条件,确保循环体至少执行一次。
    • 语法:

    do {// 循环体
    } while (循环条件);
    
    • 示例:

    int num = 5;
    do {System.out.println("num: " + num);num--;
    } while (num > 3);
    
  4. 循环控制关键字
    • break:立即终止当前所在的循环或switch,跳出代码块。
    • continue:跳过当前循环的剩余代码,直接进入下一次循环判断。

四、类与对象

类与对象是面向对象编程的核心,类是对象的模板,对象是类的实例。

(一)类的结构

类包含属性(成员变量)、方法、构造器、代码块等组件,共同描述对象的特征和行为。

  1. 属性(成员变量):用于存储对象的状态信息,声明在类中、方法外,有默认初始值(如int默认 0,String默认null)。
    • 示例:public class Person { String name; int age; }nameage即为Person类的属性。
  2. 方法:用于定义对象的行为,包含方法名、参数列表、返回值类型、方法体。
    • 示例:

    public class Person {public void sayHello() {System.out.println("Hello!");}
    }
    
  3. 构造器:与类名相同,无返回值类型,用于创建对象时初始化属性,若未自定义,编译器会生成默认无参构造器。
    • 示例:

    public class Person {String name;// 自定义构造器public Person(String name) {this.name = name;}
    }
    
  4. 代码块:分为静态代码块和实例代码块,用于初始化资源。
    • 静态代码块:用static修饰,类加载时执行,仅执行一次,优先于构造器。
    • 实例代码块:无static修饰,创建对象时执行,每次创建对象都会执行。
    • 示例:

    public class Person {// 静态代码块static {System.out.println("类加载时执行");}// 实例代码块{System.out.println("创建对象时执行");}
    }
    

(二)访问权限修饰符

访问权限修饰符用于控制类、属性、方法的访问范围,保障代码安全性和封装性,共 4 种。

修饰符同一类中同一包中同包子类中不同包中
public✔️✔️✔️✔️
protected✔️✔️✔️
默认(无修饰符)✔️✔️
private✔️
  • 应用场景:
    • private:修饰属性,仅本类可访问,通过getter/setter对外暴露访问接口。
    • public:修饰对外提供的类、方法,方便外部调用。

(三)封装

封装是面向对象三大特性之一,核心是 “隐藏内部细节,暴露安全接口”,通过private修饰属性、提供publicgetter/setter方法实现。

  • 示例(参考Person.java):

public class Person {// private修饰属性,隐藏内部细节private String name;private int age;// getter方法:获取属性值public String getName() {return name;}// setter方法:设置属性值,可添加验证逻辑public void setName(String name) {// 验证姓名不为空if (name != null && !name.isEmpty()) {this.name = name;}}
}
  • 优势:保护数据完整性,避免非法赋值;降低代码耦合度,便于后续维护和扩展。

五、继承与多态

继承与多态是面向对象编程的重要特性,实现代码复用和灵活扩展。

(一)继承

继承通过extends关键字实现,子类继承父类的非私有属性和方法,Java 支持单继承(一个子类只能有一个直接父类)。

  1. 继承的核心特性
    • 子类可直接使用父类的非私有成员,减少代码重复。
    • 子类可重写父类方法,实现个性化逻辑。
    • 通过super关键字调用父类的构造器、属性、方法。
  2. 示例

// 父类
public class Animal {public void eat() {System.out.println("动物进食");}
}// 子类,继承Animal
public class Dog extends Animal {// 重写父类eat方法@Overridepublic void eat() {System.out.println("狗吃骨头");}
}

(二)抽象类

抽象类用abstract关键字修饰,是包含抽象方法的类,不能实例化,需通过子类继承并实现抽象方法使用。

  1. 抽象类的特性
    • 可包含抽象方法(无方法体,用abstract修饰)和具体方法(有方法体)。
    • 非抽象子类继承抽象类后,必须实现所有抽象方法;若子类也为抽象类,可不用实现。
  2. 示例(参考Test02.java

// 抽象父类
abstract class Animal {String name;// 具体方法public void sleep() {System.out.println(name + "在睡觉");}// 抽象方法public abstract void eat();
}// 非抽象子类,实现抽象方法
class Dog extends Animal {public Dog(String name) {this.name = name;}@Overridepublic void eat() {System.out.println(name + "吃骨头");}
}

(三)多态

多态是指同一行为在不同对象上有不同表现形式,核心是 “父类引用指向子类对象”(向上转型),需满足 “继承”“方法重写”“向上转型” 三个条件。

  1. 多态的实现
    • 向上转型:自动转换,父类引用指向子类对象,可调用父类声明的方法,实际执行子类重写的实现。
    • 示例(参考Test02.java):

    Animal dog = new Dog("旺财"); // 向上转型
    dog.eat(); // 执行Dog类的eat(),输出“旺财吃骨头”
    dog.sleep(); // 执行Animal类的sleep(),输出“旺财在睡觉”
    
  2. 多态的优势
    • 提高代码灵活性:同一方法调用可根据对象实际类型执行不同逻辑。
    • 便于扩展:新增子类(如Cat)时,无需修改使用父类的代码,符合 “开闭原则”。
  3. instanceof运算符:用于判断对象的实际类型,避免转型错误,返回值为boolean类型。
    • 示例:

    Animal animal = new Dog("旺财");
    System.out.println(animal instanceof Dog); // true(animal实际是Dog对象)
    System.out.println(animal instanceof Animal); // true(Dog是Animal子类)
    

六、接口

接口是一种行为规范,用interface关键字定义,用于约束类的行为,不关注具体实现,弥补 Java 单继承的局限性。

(一)接口的结构

接口包含抽象方法、默认方法(JDK8+)、静态方法(JDK8+),所有成员默认用public修饰(可省略)。

  1. 抽象方法:无方法体,实现类必须重写。
  2. 默认方法:用default修饰,有方法体,实现类可选择重写或直接使用。
  3. 静态方法:用static修饰,有方法体,属于接口本身,通过接口名直接调用,实现类不能重写。
  4. 示例(参考Flyable.java

public interface Flyable {// 抽象方法void fly();// 默认方法default void land() {System.out.println("默认降落");}// 静态方法static void info() {System.out.println("这是飞行接口");}
}

(二)接口的实现

类通过implements关键字实现接口,可同时实现多个接口,需重写所有接口的抽象方法。

  1. 示例(参考Bird.javaTest02.java

// 实现Flyable接口
class Bird implements Flyable {// 重写抽象方法fly()@Overridepublic void fly() {System.out.println("鸟儿飞翔");}// 重写默认方法land()(可选)@Overridepublic void land() {System.out.println("鸟儿降落");}
}// 测试
public class Test02 {public static void main(String[] args) {Flyable bird = new Bird();bird.fly(); // 输出“鸟儿飞翔”bird.land(); // 输出“鸟儿降落”Flyable.info(); // 输出“这是飞行接口”(调用静态方法)}
}
  1. 接口的优势
    • 降低耦合度:接口定义规范,实现类可独立变化,如新增Plane类实现Flyable接口,无需修改原有代码。
    • 支持多实现:一个类可实现多个接口,满足多种行为需求,如class Plane implements Flyable, Runnable

七、内部类

内部类是定义在另一个类(外部类)内部的类,根据位置和修饰符分为成员内部类、静态内部类、局部内部类、匿名内部类,此处重点介绍成员内部类(参考Outer.java)。

(一)成员内部类的特性

成员内部类定义在外部类内部、方法外,无static修饰,与外部类实例关联。

  1. 访问权限:可直接访问外部类的所有成员(包括private修饰的成员),外部类需通过内部类实例访问内部类成员。
  2. 创建方式
    • 外部类内部:直接new 内部类()创建。
    • 外部类外部:需先创建外部类实例,再通过外部类实例.new 内部类()创建。
  3. 示例(参考Outer.java

public class Outer {private int outerVar = 10; // 外部类私有成员// 成员内部类class Inner {int innerVar = 20;public void innerMethod() {// 访问外部类私有成员System.out.println("外部类变量:" + outerVar);System.out.println("内部类变量:" + innerVar);}}// 外部类方法中使用内部类public void outerMethod() {Inner inner = new Inner(); // 外部类内部创建内部类实例inner.innerMethod();}public static void main(String[] args) {// 外部类外部创建内部类实例Outer outer = new Outer();Outer.Inner inner = outer.new Inner();inner.innerMethod(); // 输出“外部类变量:10”“内部类变量:20”}
}

(二)成员内部类的应用场景

  • 当内部类仅服务于外部类,且需要频繁访问外部类成员时使用,可隐藏内部实现细节,提高代码封装性,如事件监听器、迭代器等场景。

八、关键字补充

(一)final

final用于修饰类、方法、变量,表示 “不可变”。

  1. 修饰类:类不能被继承,如final class String,确保类的稳定性。
  2. 修饰方法:方法不能被重写,如父类中final修饰的方法,子类无法修改其逻辑。
  3. 修饰变量
    • 基本数据类型变量:初始化后值不可改变。
    • 引用数据类型变量:初始化后内存地址不可改变,但对象内容可修改。
    • 示例:

    final int a = 5;
    // a = 6; // 报错:基本类型变量值不可变final int[] arr = {1, 2, 3};
    arr[0] = 100; // 允许:修改数组内容
    // arr = new int[5]; // 报错:引用地址不可变
    

(二)static

static用于修饰属性、方法、代码块,属于类本身,而非对象实例。

  1. 静态属性:所有对象共享同一数据,通过类名.属性名访问,如Student.school(参考Test01.java)。
    • 示例:

    class Student {static String school; // 静态属性
    }
    Student.school = "河金";
    System.out.println(Student.school); // 输出“河金”
    
  2. 静态方法:属于类,通过类名.方法名访问,不能访问非静态成员(非静态成员依赖对象实例),如Student.eat()(参考Test01.java)。
    • 示例:

    class Student {public static void eat() {System.out.println("吃饭");}
    }
    Student.eat(); // 直接通过类名调用
    
  3. 注意:静态成员加载时机早于非静态成员,在静态方法中不能使用thissuper关键字。

(三)this

this代表当前对象的引用,用于区分成员变量和局部变量、调用当前类的构造器、调用当前类的方法。

  • 示例:

public class Person {private String name;public Person(String name) {this.name = name; // 区分成员变量和局部变量}
}

九、数组

数组是存储相同类型数据的容器,属于引用数据类型,长度固定(初始化后不可改变)。

(一)数组的声明与初始化

  1. 声明方式:两种语法等价,推荐第一种,更符合 Java 风格。
    • 数据类型[] 数组名,如int[] arr
    • 数据类型 数组名[],如int arr[]
  2. 初始化方式
    • 静态初始化:指定数组元素,长度由元素个数决定,如int[] arr = {1, 2, 3};
    • 动态初始化:指定数组长度,元素为默认值,如int[] arr = new int[3];(元素默认值为 0)。

(二)数组的访问与遍历

  1. 访问:通过 “数组名 [索引]” 访问元素,索引从 0 开始,最大索引为 “数组长度 - 1”,若索引越界会抛出ArrayIndexOutOfBoundsException
    • 示例:int[] arr = {1, 2, 3}; System.out.println(arr[0]);(输出 1)。
  2. 遍历:通过for循环或增强for循环(for-each)遍历数组元素。
    • 示例:

    int[] arr = {1, 2, 3};
    // 普通for循环
    for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);
    }
    // 增强for循环
    for (int num : arr) {System.out.println(num);
    }
    

十、字符串比较

字符串比较是常见操作,需区分==equals()的差异,避免逻辑错误。

(一)==的作用

  • 基本数据类型:比较值是否相等,如int a = 10, b = 10; System.out.println(a == b);(输出true)。
  • 引用数据类型:比较对象的内存地址是否相同,即是否指向同一个对象,如String s1 = new String("abc"), s2 = new String("abc"); System.out.println(s1 == s2);(输出false,因s1s2是两个不同对象)。

(二)equals()的作用

equals()Object类的方法,默认实现与==一致(比较内存地址),但许多类(如StringInteger)重写了该方法,用于比较对象内容是否相等。

  1. String类的equals():比较字符串的字符序列是否相同,与内存地址无关。
    • 示例:

    String s1 = new String("abc");
    String s2 = new String("abc");
    System.out.println(s1.equals(s2)); // 输出true(内容相同)
    
  2. 自定义类重写equals():若需比较自定义对象的内容,需手动重写equals()方法,通常需同时重写hashCode()方法(保证 “equals 相等的对象,hashCode 一定相等”)。
    • 示例:

    public class Person {private String name;@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return Objects.equals(name, person.name);}@Overridepublic int hashCode() {return Objects.hash(name);}
    }

http://www.dtcms.com/a/515483.html

相关文章:

  • UE5 C++ CVar控制台命令字段使用
  • 从图像处理到AI识别:直播美颜sdk如何实现高效一键美颜?
  • ESD防护设计宝典(十三):电快速瞬变脉冲群(EFT)防护与整改
  • 做百度推广去些网站加客户二级域名免费申请网站
  • 婚介 东莞网站建设西部数码网站源码
  • 云计算实验4——CentOS中HBase的安装
  • Excel文件中的VBA脚本,在文件使用WPS编辑保存后无法执行
  • LLD(详细设计文档)输出标准模板
  • 【山西政务服务网-注册_登录安全分析报告】
  • 云原生安全深度实战:从容器安全到零信任架构
  • Java导出写入固定Excel模板数据
  • 合肥网站建设模板系统html怎么做商品页面
  • uniapp微信小程序页面跳转后定时器未清除问题解析与解决方案
  • 《从“直接对话”到 “集成开发调用”:智谱 GLM-4.6 引领 Coding 场景的效率跃迁》
  • 数据中心基础设施等级
  • 关于架空输电线识别树障or测距相关论文阅读
  • [go 面试] 深入理解并发控制:掌握锁的精髓
  • TypeScript 面试题及详细答案 100题 (61-70)-- 泛型(Generics)
  • 全球外贸网站制作教程icp网站快速备案
  • 《Hiding Images in Diffusion Models by Editing Learned Score Functions》 论文阅读
  • 频率分集阵列雷达——论文阅读
  • 网站备案信息如何下载潍坊市住房和城乡建设局网站下载
  • 比较好的企业网站百度举报网站
  • 数据库加密技术
  • nginx配置内嵌网页
  • 【微服务】SpringBoot 整合轻量级安全框架JWE 项目实战详解
  • 一个完整的AI项目从需求分析到部署的全流程详解
  • UE5 材质-14:减法subtract节点适用于向量与标量,数学 if 组件,由已遮罩材质结合自发光参数,周期性改变蒙版的大小,实现溶解效果
  • 构建AI智能体:七十一、模型评估指南:准确率、精确率、F1分数与ROC/AUC的深度解析
  • 基于脚手架微服务的视频点播系统-客户端业务逻辑处理部分(二)