Java相关知识
抽象类
在Java中,抽象类是一种特殊的类,它不能被实例化,只能作为基类被继承,并且必须用 abstract 关键字来修饰。
抽象类的本质就是一个类模板,它提供了一些抽象的方法和属性,让子类来具体实现。抽象类不能被实例化,但是可以用来定义变量类型、创建引用对象等。相比于普通类,抽象类具有以下特点:
- 抽象类不能被实例化。因为它只是一个抽象的概念,不能直接创建对象。
- 抽象类可以包含抽象方法和非抽象方法。抽象方法是没有实现的方法,只有声明,而非抽象方法则是已经实现的方法。
- 子类必须实现父类中的所有抽象方法。否则,子类也必须声明为抽象类。
- 抽象类可以拥有属性和构造方法。【抽象类的构造函数主要是给子类调用以便初始化抽象类的一些属性】
接口
在Java中,接口是一种特殊的抽象类,它定义了一个规范,但没有具体实现。接口与抽象类不同的是,接口中所有方法都是抽象的【默认为 public abstract 类型】,并且不能拥有成员变量(只能拥有常量)。接口可以被类实现,也可以被其他接口扩展。
接口和抽象类本身不能实例化,但可以指向子类的实例,这是java多态的一种体现。
反射
Java反射机制是指在运行时动态地获取类的信息并对其进行操作的能力。通过反射,可以在程序运行时获取类的全限定名、属性、方法等信息,并且可以在运行时调用类的构造器、方法或者改变属性值。
Java反射机制包含以下三个核心类:Class、Constructor和Method。其中,Class类代表一个类的运行时信息,Constructor类表示类的构造器信息,Method类表示类的方法信息。
使用反射机制的前提是需要获得一个类的Class对象,可以使用以下几种方式获取一个类的Class对象:
- 调用某个对象的getClass()方法;
- 使用.class语法获取;
- 使用Class.forName()方法获取。
一旦获取了一个类的Class对象,就可以通过它来获取该类的构造器、方法和属性等信息,并且可以在运行时调用这些方法,修改属性值,实例化对象等。
Java反射机制可以使编程更加灵活,但同时也会降低程序的性能和安全性,应当慎重使用。
注解
注解(Annotation)是Java编程语言中的一个特性,是一种元数据【Matadata,用于描述数据的数据,包括数据内容、格式、结构等信息。元数据通常是通过注解、XML配置文件、属性文件等形式来提供的,可以使得程序具有更高的可配置性,通过修改元数据来改变程序而无需修改代码】,可以用来为程序中的方法、类、变量等添加额外的信息和说明。
内存溢出与内存泄露
内存溢出(Memory Overflow)指的是程序在申请内存时,要求的内存大小超过了系统所能提供的可用内存大小,导致程序运行失败。通常情况下,内存溢出会导致程序崩溃或者异常结束,并且在操作系统中会生成一个错误报告。
而内存泄露(Memory Leak)则是指程序在申请内存后,在释放该内存之前,失去了对这块内存的引用,从而导致这块内存无法被再次使用,最终可能导致系统内存逐渐耗尽,影响整个系统的正常运行。内存泄露通常不会导致程序直接崩溃,但会导致程序的性能和稳定性受到影响。
关键字final
final代表最终的,不可改变。可以修饰类、方法、成员变量、局部变量。
final修饰类时则此类不能再有子类。且类的方法也不能被重写
final修饰方法时表示方法不能被覆盖重写
所以对于类和方法来说,final与abstract不能同时使用。
final修饰具备变量只能有一次赋值,可以在初始化的时候也可以在之后赋值,但是只有一次。赋值之后不可改变。对于引用类型来说,不可变说的是变量当中的地址值不可改变,所以引用类型的成员变量等是可以改变的。
final修饰成员变量,也是只能一次赋值,要么声明时要么在构造函数中。没有set方法。
自动装箱与自动拆箱
自动装箱:1.把基本类型的值赋给包装类;2.基本类型的值作为参数传递给需要相应包装类的方法。 Integer.valueOf()
自动拆箱:1.把包装类的值赋给基本类型数据;2.包装类作为参数传递给需要相应基本数据类型的方法。intValue()
类初始化
类的加载顺序是 静态代码块>初始化属性值>普通代码块>构造方法
如果初始化一个类的时候其父类尚未初始化则优先初始化其父类
构造函数也只有在调用的时候会执行,如果类中定义静态成员变量对象,会先创建对象调用构造方法。
子类的构造函数会默认添加父类的空参构造函数,也可以使用super(“args”)主动调用带参构造函数。super()必须放在构造函数的第一行,所以父类构造函数先于子类构造函数初始化。
所以子类初始化时是父类static 子类static 然后 父类构造函数、子类构造函数
1 | //例子 |
控制访问
Java使用访问权限修饰符修饰类、成员变量、成员函数、内部类以控制对其的访问权限
:同类 同包 不同包子类
同类 | 同包 | 不同包子类 | 不同包其他类 | |
---|---|---|---|---|
public 公共权限 | 是 | 是 | 是 | 是 |
protected 保护权限 | 是 | 是 | 是 | |
default 默认权限 | 是 | 是 | ||
private 私有权限 | 是 |
引用类型
Java中基本数据类型的值直接存放在虚拟机栈中,引用类型的值则是存放在堆内存中,虚拟机栈保存指向堆内存的地址。
Java中最初对引用类型的变量只分为了有引用和无引用两类,对于无引用的变量则会在GC中回收内存空间。这种方法存在缺陷,有的有引用的变量其实也是可以回收的,比如缓存的图片等。
所以后来Java堆引用的概念进行了扩展,设计了四种引用类型:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)
强引用
new一个对象或数组就是一个强引用,强引用具有以下特点:
1.JVM内存不足时,即使抛出OOM(out of memory)也不会回收被强引用关联的对象。
2.可以直接通过引用进行访问。
3.通过将强引用设置为null,可以断开强引用与对象之间的关联。
软引用
软引用关联的对象生命力较强引用更弱,在内存不足时会被回收。需要通过SoftReference创建对象的软引用。
1.被软引用的对象不能直接使用,需要通过get()方法获取;
2.只被软引用关联的对象在内存不足的时候会被回收。
3.适用于对内存敏感的高速缓存,例如图片缓存框架中的图片缓存可以使用软引用。
4.软引用可以关联一个引用队列,如果能从引用队列中poll出软引用,说明软引用关联的对象已经被回收。
1 | //创建强引用 |
弱引用
弱引用关联的对象生命力比软引用更弱,无论内存是否充足,都会被回收。
需要使用WeakReference创建。
1.关联对象不能直接访问,需要使用get()
2.无论内存是否充足都会被回收。
3.适用于对内存敏感的缓存。
4.弱引用也可以关联引用队列,实现对弱引用的管理和对关联对象的监听。
- Thread中,存储<ThraeadLocal, value>的entry中,对
ThraeadLocal
的引用就是弱引用。
虚引用
虚引用又叫幻影引用,对被关联的对象生命周期没有任何影响。
可以使用PhantomReference
创建虚引用。
1.任何时候都可能被垃圾回收;
2.不影响被关联对象的生命周期,无法通过虚引用get()到被关联的对象。
3.虚引用可以用来判断对象是否已经被回收