找回密码
 立即注册
首页 业界区 科技 java专项八股知识点(1)

java专项八股知识点(1)

蔓好 2025-6-8 12:00:35
目录


  • 外部类&内部类
  • String、StringBuilder和StringBuffer的区别
  • super和this关键字

1.png

  在 Java 中,类可以分为外部类内部类

  • 外部类是最常见的类,定义在 .java 文件的顶层。它可以用修饰符如 public、default、abstract、final 修饰,但不能使用 static 修饰。一个源文件中最多只能有一个 public 外部类,且文件名必须与该类名一致。外部类适合承载完整的业务逻辑,如服务类、控制器类、实体类等。
  • 内部类是定义在另一个类内部的类,主要有三种类型:成员内部类静态内部类匿名内部类。其中,只有静态内部类可以使用 static 修饰。成员内部类和匿名内部类都可以访问外部类的属性和方法,即使这些成员是私有的。静态内部类无法访问外部类的非静态成员。
  从编译结果来看,外部类会被编译为 Outer.class,而内部类会被编译为 Outer$Inner.class 的字节码文件。
  在实际开发中,内部类常用于构建辅助结构,增强封装性。例如:

  • 使用静态内部类实现 Builder 模式;
  • 使用匿名内部类实现按钮点击事件或线程回调;
  • 使用成员内部类管理与外部类高度耦合的数据结构。
(1)成员内部类(非静态)
  成员内部类定义在类的内部,但不是静态的,因此它可以访问外部类的所有成员,包括私有变量。通常用于表达**“整体-部分”关系**,比如学校和学生、公司和员工。
应用场景:


  • 一个类的数据对象高度依赖外部类的上下文(如组织内的成员、设备内的部件)
  1. public class School {
  2.     private String name = "大学";
  3.     // 成员内部类
  4.     public class Student {
  5.         private String studentName;
  6.         public Student(String studentName) {
  7.             this.studentName = studentName;
  8.         }
  9.         public void introduce() {
  10.             // 可以访问外部类成员
  11.             System.out.println("我是 " + studentName + ",来自 " + name);
  12.         }
  13.     }
  14.     public static void main(String[] args) {
  15.         School school = new School();
  16.         Student stu = school.new Student("小明");
  17.         stu.introduce();
  18.     }
  19. }
复制代码
 (2)静态内部类
  静态内部类是用 static 修饰的内部类。它不能访问外部类的非静态成员,更像一个逻辑上嵌套的独立类,常用于Builder 模式工具类组装等场景。
  1. public class User {
  2.     private String name;
  3.     private int age;
  4.     // 静态内部类 - Builder 模式
  5.     public static class Builder {
  6.         private String name;
  7.         private int age;
  8.         public Builder name(String name) {
  9.             this.name = name;
  10.             return this;
  11.         }
  12.         public Builder age(int age) {
  13.             this.age = age;
  14.             return this;
  15.         }
  16.         public User build() {
  17.             User user = new User();
  18.             user.name = this.name;
  19.             user.age = this.age;
  20.             return user;
  21.         }
  22.     }
  23.     @Override
  24.     public String toString() {
  25.         return name + " - " + age;
  26.     }
  27.     public static void main(String[] args) {
  28.         User user = new User.Builder()
  29.                 .name("张三")
  30.                 .age(25)
  31.                 .build();
  32.         System.out.println(user);
  33.     }
  34. }
复制代码
(3)匿名内部类
  匿名内部类是没有名字的内部类,常用于临时实现接口或继承类的逻辑,适用于只用一次的情况,比如线程创建、回调事件处理。
  1. public class Test {
  2.     public static void main(String[] args) {
  3.         // 使用匿名内部类创建线程
  4.         Thread t = new Thread(new Runnable() {
  5.             @Override
  6.             public void run() {
  7.                 System.out.println("线程已启动!");
  8.             }
  9.         });
  10.         t.start();
  11.     }
  12. }
复制代码
2.png

 (1)String(不可变字符串)
   String底层是final char[],它是不可变的,所有字符串拼接、替换、substring等操作,都会创建新对象。不可变性有一些好处:

  • 线程安全(多个线程共享同一个字符串不会有并发问题)
  1. String s = "hello";
  2. Thread t1 = new Thread(() -> {
  3.     System.out.println(s);
  4. });
  5. Thread t2 = new Thread(() -> {
  6.     System.out.println(s);
  7. });<br>两个线程都在访问s,但因为String是不可变的,所以很安全:<br>- 内部的char[]是final;<br>- 无法修改字符串内容,只能重新赋值;<br>- 无论多少线程读同一个字符串,都不会出现竞态条件。
复制代码

  • 可以被安全缓存(字符串常量池)
Java 中有个优化机制叫 字符串常量池(String Pool)
  1. String a = "abc";
  2. String b = "abc";
  3. System.out.println(a == b);  // true,指向同一个地址
复制代码

  • JVM 会自动把 字符串字面量缓存到堆外常量池中
  • 下次用同样的字面量,就不会创建新对象,而是复用;
  • 前提是:对象不可变,否则池里的值就可能被污染!


来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册