JavaSE知识点总结

1、intern()方法

“ab”.intern():这个方法会首先检查字符串池中是否有”ab”这个字符串,如果存在则返回这个字符串的引用,否则就将这个字符串添加到字符串池中,然后返回这个常量池中字符串的引用。以下代码是在jdk1.8中测试,jdk1.6会有所不同。

public static void main(String[] args) {

	  // 创建2个对象,一个String对象在堆中,一个String常量在常量池
	  String s = new String("2");
	  // 判断s是否在常量池中,存在则返回常量池中对象的引用,此时intern指向常量池中的对象
	  String intern = s.intern();
	  // s2字符串在常量池中,所以返回常量池中的对象引用
	  String s2 = "2";
	  // s:为堆中对象  s2:为常量池对象  所以:false
	  System.out.println(s == s2); // false
	  // intern和s2都是指向常量池中的字符串,所以:true
	  System.out.println(intern == s2);  // true
	  System.out.println("------------------------");
	
	  // 创建4个对象:堆中"33","3","3"对象,常量池:"3"对象
	  String s3 = new String("3") + new String("3");
	  // 判断s3是否在常量池中,不存在则将s3加入常量池中,并且常量池中保存的是s3的引用,返回常量池中对象的引用,此时s3和intern2指向同一个对象
	  String intern2 = s3.intern();
	  // s4字符串在常量池中,所以返回常量池中的对象引用
	  String s4 = "33";
	  // s3和intern2和s4指向的是同一个对象
	  System.out.println(s3 == s4);  // true
	  System.out.println(intern2 == s3);  // true
	  System.out.println(intern2 == s4);  // true

}
2、try…catch…finally
// 返回 40
public static int fun(){
    int a = 10;
    try{
        System.out.println(a / 0);
        a = 20;
       // return a;
    }catch (Exception e){
        a = 30;
        return a;
    }finally {
        a = 40;
        return a;
    }
}
// 返回 30
public static int fun(){
    int a = 10;
    try{
        System.out.println(a / 0);
        a = 20;
       // return a;
    }catch (Exception e){
        a = 30;
        return a;
    }finally {
        a = 40;
    }
    return a;
}
// 返回 30
public static int fun(){
    int a = 10;
    try{
        System.out.println(a / 0);
        a = 20;
        return a;
    }catch (Exception e){
        a = 30;
        return a;
    }finally {
        a = 40;
    }
}
3、hashCode和equals的关系
  1. equals相等的两个对象,hashCode一定相等
  2. hashCode相等的两个对象,equals不一定相等

使用Object.hashCode,是根据随机算法生成的hashCode值,无法保证两个对象equals相等的时候,hashCode也相等。

像一些集合容器map,在进行比较两个对象相等的判定条件是hashcode和equals都相等,所有在重写equals时,必须要重写hashCode,才能保证集合容器的正确使用。

4、什么是反射,反射有什么缺点?

反射是指在程序运行时动态获取类的信息、调用类的方法、访问类的属性等操作能力。在Java中,反射允许程序在运行时检查和操作类、方法、字段等,使得程序可以在运行时动态地创建对象、调用方法、修改属性等。

反射的缺点包括:

  • 性能问题:由于反射涉及到动态查找和调用,相比直接调用方法,反射的性能会有一定的损耗。反射操作通常比直接操作更慢,因此在性能要求较高的场景下,应该谨慎使用反射。
  • 安全问题:反射可以访问和修改类的私有方法和属性,可能会破坏类的封装性,导致安全隐患。使用反射时需要格外小心,确保不会对程序的安全性造成影响。
  • 可读性和维护性差:由于反射是在运行时动态获取类信息,代码的可读性和维护性可能会受到影响。反射使得代码结构不够清晰,增加了代码的复杂性,降低了代码的可读性和维护性。
  • 编译器检查失效:使用反射可以绕过编译器的类型检查,可能导致运行时的类型错误,增加了程序出错的可能性。因此,在使用反射时需要格外小心,确保类型安全。
  • 不利于性能优化:由于反射的灵活性和动态性,使得程序的结构和行为不够明确,不利于编译器进行优化,可能影响程序的性能表现。
5、BIO、NIO、AIO的区别
6、面向对象的理解?

面向对象的核心是将现实世界的实体抽象为代码中的’对象’,每个对象包含数据(属性)和操作数据的方法,形成高内聚低耦合的模块。这样设计更符合人类思维方式,让程序结构更清晰。它有四大特性:

  • 封装:将数据和方法封装在类内部,隐藏内部细节,只暴露必要接口,提高安全性和维护性
  • 继承:实现代码复用,建立类之间的层次关系
  • 多态:同一接口多种实现,提高代码灵活性、拓展性
  • 抽象:简化复杂系统,如定义业务接口契约

在过往的项目中,面向对象的思想和特性帮助我们:快速响应需求变更、降低代码维护成本、提高代码质量。但我们也要平衡面向对象与其他范式(函数式编程)的优势,防止过度设计,增加系统的复杂度。

7、什么是抽象类?

抽象类是用来捕捉子类通用特性的类,它不能被实例化,只能作为其他类的父类。

抽象类特点:

  • abstract 关键字声明
  • 可以包含抽象方法和具体方法
  • 可以有构造方法、成员变量
  • 子类继承使用 extends
  • 一个类只能继承一个抽象类(单继承)
8、什么是接口?

接口是行为的抽象,定义了一组方法规范,实现类必须遵守这些规范。

接口特点:

  • interface 关键字声明
  • Java 8之前:只能有抽象方法和常量
  • Java 8+:可以有默认方法、静态方法
  • Java 9+:可以有私有方法
  • 实现类使用 implements
  • 一个类可以实现多个接口
9、抽象类和接口的区别?
  1. 设计理念不同:抽象类是’is-a’关系,接口是’has-a’关系
  2. 单继承 vs 多实现:Java中类只能继承一个父类,但可实现多个接口
  3. 抽象类可以有构造方法和具体实现,早期接口只能有抽象方法
  4. 成员变量方面,抽象类可以是普通变量,接口只能是常量
10、什么是泛型?

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。

泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

好处: 1.可以将运行期的异常提前到编译期;2.消除强制类型转换;3.提高了类型安全

泛型的三种方式: 泛型类,泛型接口,泛型方法

11、异常

Java中所有异常和错误的根类是Throwable,它有两个直接子类:ErrorException(受检异常 or 非受检异常)

  1. 定义:异常是程序运行过程中发生的不正常事件,会打断正常的指令流。
  2. 分类:分为受检异常和非受检异常(错误和运行时异常)。
  3. 异常处理机制:try-catch-finally,throw和throws。
  4. 自定义异常:可以通过继承Exception或RuntimeException来创建自定义异常。
  5. 最佳实践:例如,不要吞掉异常,不要使用异常控制流程,使用具体的异常类型等。
  • 常见运行时异常:

    1. NullPointerException
      空指针异常,JAVA8中可用Optional来避免,一般是代码中出现了空对象时,抛出该异常

    2. IndexOutOfBoundsException
      数组下标越界异常,当使用的数组下标超出数组允许范围时,抛出该异常

    3. ClassCastException
      类型转换异常,当试图将对象强制转换为不是实例的子类时,抛出该异常

    4. NumberFormatException
      数字格式化异常,当试图将一个String转换为指定的数字类型,而该字符串确不满足数字类型要求的格式时,抛出该异常

    5. JSONException
      JSON异常,进行JSON格式化操作时出现异常,会抛出该异常

    6. ArithmeticException

      算术异常

  • 常见检查性异常:

    1. SQLException
      SQL异常
    2. IOException
      IO异常,在对流操作时有可能会出现的异常
    3. FileNotFoundException
      找不到某个文件时,会抛出该异常
    4. ClassNotFoundException
      找不到某个类时,会抛出该异常
    5. InterruptedException
      中断异常
12、注解

Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。继承自java.lang.annotation.Annotation。注解本身不影响代码逻辑,但可以通过反射获取注解信息。

package java.lang.annotation;
public interface Annotation {
    boolean equals(Object obj);
    int hashCode();
    String toString();
    Class<? extends Annotation> annotationType();
}

内置注解:

  • @Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
  • @Deprecated - 标记过时方法。如果使用该方法,会报编译警告。
  • @SuppressWarnings - 指示编译器去忽略注解中声明的警告。
  • @SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。
  • @FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。
  • @Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。

自定义注解:

@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation1 {
}

元注解:
元注解的作用就是负责注解其他注解,Java定义了4个标准的meta-annotation类型,他们被用来提供对其他annotion类型作说明。

  • @Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
  • @Documented - 标记这些注解是否包含在用户文档中。
  • @Target - 标记这个注解应该是哪种 Java 成员。
  • @Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)

@Retention 的取值:

public enum RetentionPolicy {
    SOURCE,            /* Annotation信息仅存在于编译器处理期间,编译器处理完之后就没有该Annotation信息了  */
    CLASS,             /* 编译器将Annotation存储于类对应的.class文件中。默认行为  */
    RUNTIME            /* 编译器将Annotation存储于class文件中,并且可由JVM读入 */
}

@Target的取值:

public enum ElementType {
    TYPE,               /* 类、接口(包括注释类型)或枚举声明  */
    FIELD,              /* 字段声明(包括枚举常量)  */
    METHOD,             /* 方法声明  */
    PARAMETER,          /* 参数声明  */
    CONSTRUCTOR,        /* 构造方法声明  */
    LOCAL_VARIABLE,     /* 局部变量声明  */
    ANNOTATION_TYPE,    /* 注释类型声明  */
    PACKAGE             /* 包声明  */
}

注解的主要价值:

  • 编译检查:如@Override确保正确重写方法
  • 框架配置:如Spring的@Autowired、@Service简化配置
  • 代码生成:如Lombok的@Data自动生成代码
  • 测试标记:如JUnit的@Test
13、反射

反射就是在运行状态能够动态的获取该类的属性和方法,并且能够任意的使用该类的属性和方法,这种动态获取类信息以及动态的调用对象的方法的功能就是反射。它让Java在运行时具有像动态语言一样的特性。

核心功能包括:

  • 动态获取类信息(Class对象)
  • 创建对象(newInstance)
  • 调用方法(invoke)
  • 访问/修改字段(get/set)
  • 处理注解和泛型

关键类:

  • Class:类的元数据入口
  • Field:字段信息
  • Method:方法信息
  • Constructor:构造方法
  • Modifier:修饰符信息

实际应用场景:

  • 框架开发:Spring通过反射实现依赖注入
  • 动态代理:AOP切面编程
  • 序列化工具:Jackson/GSON处理JSON
  • 测试框架:JUnit发现并运行测试方法
  • 插件系统:动态加载和扩展功能

优点:

  • 灵活性高,实现动态编程
  • 框架开发的基础设施
  • 支持运行时类型检查

缺点:

  • 性能开销:反射操作比直接调用慢
  • 安全问题:可以绕过访问控制
  • 代码复杂:降低可读性和维护性
  • 编译检查缺失:错误在运行时才发现

性能优化:

  • 缓存反射对象
  • 使用setAccessible(true)减少检查
  • 避免在热点代码中使用反射

获取class对象三种方式:

  1. 类名.class 如:Person.class 该方式安全可靠,程序性能最高
  2. 对象.getClass() 如:person.getClass()
  3. Class.forName(全类名) 如:Class.forName(“ldc.org. demo.person”)

总结:

反射是Java在运行时动态获取和操作类信息的能力。通过Class对象可以获取字段、方法、构造器等信息,并能创建对象、调用方法、访问字段。它广泛应用于框架开发(如Spring)、动态代理、序列化等场景。优点是灵活性高,缺点是性能差、安全性低。实际使用中需要注意性能优化和安全控制。

14、static和final的区别?以及分别存储在JVM的哪个区域?
维度staticfinal
语义类级成员,与对象无关值/引用只能赋一次
内存份数整个 JVM 只有一份与普通字段份数相同
生命周期类加载即分配,卸载才回收一旦赋值就冻结
可变性可反复修改不可再改(基本类型值不变,引用类型地址不变)
能否叠加✅ 可单独用✅ 可单独用
叠加后类级常量(编译期或运行期确定)仍是“只能一次”语义
类型static存储位置实例 final存储位置static final存储位置(优化后,值直接内联到使用处,引用存在堆(Class对象中))局部变量
基本类型变量堆(Class对象中)堆对象中元空间(运行时常量池)
字符串变量堆(Class对象中的引用) + 堆(字符串常量池)堆对象的引用 --> 堆(字符串常量池)元空间(运行时常量池)–> 堆(字符串常量池)栈引用–> 堆(字符串常量池)
对象引用堆(Class对象中的引用) + 堆对象堆对象的引用 + 堆对象元空间(运行时常量池)–> 堆对象栈引用 --> 堆对象
方法元空间元空间
元空间元空间
代码块元空间
15、Linux的五种IO模型

https://blog.csdn.net/Linging_24/article/details/134984317?spm=1001.2014.3001.5501

16、Reactor线程模型详解

https://blog.csdn.net/Linging_24/article/details/134984818?spm=1001.2014.3001.5501

17、IO零拷贝

https://blog.csdn.net/Linging_24/article/details/134984466?spm=1001.2014.3001.5501

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值