java基础知识点总结

面向对象基础

继承

Java只允许单继承,所有类最终的根类是Object;

protected允许子类访问父类的字段和方法;

子类的构造方法可以通过**super()**调用父类的构造方法;

可以安全地向上转型为更抽象的类型;

可以强制向下转型,最好借助instanceof判断;

多态

final修饰符有多种作用:

(1)final修饰的方法可以阻止被覆写;
(2)final修饰的class可以阻止被继承;
(3)final修饰的field必须在创建对象时初始化,随后不可修改。

抽象类

定义了抽象方法的类是抽象类,不能被实例化;
抽象方法对应于c++的纯虚函数,关键字为abstract.
从抽象类继承的子类,若不实现抽象方法,则子类也是抽象类

接口

如果一个抽象类没有字段,所有方法全部都是抽象方法,则可以改写为接口
java基础知识点总结_第1张图片
接口比抽象类更抽象

Java内建的package机制是为了避免class命名冲突;

JDK的核心类使用java.lang包,编译器会自动导入;

JDK的其它常用类定义在java.util.,java.math.,java.text.*,……;

包名推荐使用倒置的域名,例如org.apache

位于同一个包的类,可以访问包作用域的字段和方法。不用public、protected、private修饰的字段和方法就是包作用域

作用域

定义为public的field、method可以被其他类访问,前提是首先有访问class的权限;
包作用域是指一个类允许访问同一个package的没有public、private修饰的class,以及没有public、protected、private修饰的字段和方法。
一个.java文件只能包含一个public类,但可以包含多个非public类。如果有public类,文件名必须和public类的名字相同。

Java核心类

StringBuilder

StringBuilder是可变对象,用来高效拼接字符串;

StringBuilder可以支持链式操作,实现链式操作的关键是返回实例本身;

StringBuffer是StringBuilder的线程安全版本,现在很少使用。

包装类型

Java核心库提供的包装类型可以把基本类型包装为class;

自动装箱和自动拆箱都是在编译期完成的(JDK>=1.5);

装箱和拆箱会影响执行效率,且拆箱时可能发生NullPointerException;

包装类型的比较必须使用equals();

整数和浮点数的包装类型都继承自Number;

所有的包装类型都是不变类,因此,一旦创建了Integer对象,该对象就是不变的。

记录类

从Java 14开始,提供新的record关键字,可以非常方便地定义Data Class:

使用record定义的是不变类;

可以编写Compact Constructor对参数进行验证;

可以定义静态方法。

BigInteger

BigInteger用于表示任意大小的整数;

BigInteger是不变类,并且继承自Number;

将BigInteger转换成基本类型时可使用longValueExact()等方法保证结果准确。

常用工具类

Java提供的常用工具类有:

Math:数学计算

Random:生成伪随机数

SecureRandom:生成安全的随机数

异常处理

Java异常

java基础知识点总结_第2张图片

只要是方法声明的Checked Exception,不在调用层捕获,也必须在更高的调用层捕获。所有未捕获的异常,最终也必须在main()方法中捕获,不会出现漏写try的情况。这是由编译器保证的。main()方法也是最后捕获Exception的机会。

如果是测试代码,上面的写法就略显麻烦。如果不想写任何try代码,可以直接把main()方法定义为throws Exception:

public class Main {
    public static void main(String[] args) throws Exception {
        byte[] bs = toGBK("中文");
        System.out.println(Arrays.toString(bs));
    }

    static byte[] toGBK(String s) throws UnsupportedEncodingException {
        // 用指定编码转换String为byte[]:
        return s.getBytes("GBK");
    }
}

Java的异常是class,并且从Throwable继承;

Error是无需捕获的严重错误,Exception是应该捕获的可处理的错误;

RuntimeException无需强制捕获,非RuntimeException(Checked Exception)需强制捕获,或者用throws声明;

不推荐捕获了异常但不进行任何处理。

日志

Commons Logging是使用最广泛的日志模块;

Commons Logging可以自动检测并使用其他日志模块。

通过Commons Logging实现日志,不需要修改代码即可使用Log4j;

使用Log4j只需要把log4j2.xml和相关jar放入classpath;

如果要更换Log4j,只需要移除log4j2.xml和相关jar;

只有扩展Log4j时,才需要引用Log4j的接口(例如,将日志加密写入数据库的功能,需要自己开发)。

反射

Class类

JVM为每个加载的class及interface创建了对应的Class实例来保存class及interface的所有信息;

获取一个class对应的Class实例后,就可以获取该class的所有信息;

通过Class实例获取class信息的方法称为反射(Reflection);

JVM总是动态加载class,可以在运行期根据条件来控制加载class。

动态代理

所有interface类型的变量总是通过某个实例向上转型并赋值给接口类型变量的:有没有可能不编写实现类,直接在运行期创建某个interface的实例呢?

这是可能的,因为Java标准库提供了一种动态代理(Dynamic Proxy)的机制:可以在运行期动态创建某个interface的实例。

泛型

extends通配符

使用类似通配符作为方法参数时表示:

  • 方法内部可以调用获取Number引用的方法,例如:Number n = obj.getFirst();;
  • 方法内部无法调用传入Number引用的方法(null除外),例如:obj.setFirst(Number n);。

即一句话总结:使用extends通配符表示可以读,不能写。

使用类似定义泛型类时表示:

  • 泛型类型限定为Number以及Number的子类。

super通配符

对比extends和super通配符
我们再回顾一下extends通配符。作为方法参数,类型和类型的区别在于:

  • 允许调用读方法T get()获取T的引用,但不允许调用写方法set(T)传入T的引用(传入null除外);
  • 允许调用写方法set(T)传入T的引用,但不允许调用读方法T get()获取T的引用(获取Object除外)。

集合

hashmap中依据key的hash值来确定value存储位置,所以一定要重写hashCode方法,而重写equals方法,是为了解决hash冲突,如果两个key的hash值相同,就会调用equals方法,比较key值是否相同,在存储时:如果equals结果相同就覆盖更新value值,如果不同就用List他们都存储起来。在取出来是:如果equals结果相同就返回当前value值,如果不同就遍历List中下一个元素。即要key与hash同时匹配才会认为是同一个key。

JDK中源码:if(e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))){ops;}

treemap使用自定义的compare方法存放在红黑树中,无需重写equals和hashCode。关于treemap能不能存放重复键的问题参照这篇博客:

https://blog.csdn.net/u010698072/article/details/55255073?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2aggregatepagefirst_rank_ecpm_v1~rank_v31_ecpm-6-55255073-null-null.pc_agg_new_rank&utm_term=treemap%E7%9A%84%E5%80%BC%E5%8F%AF%E4%BB%A5%E9%87%8D%E5%A4%8D%E5%90%97&spm=1000.2123.3001.4430

你可能感兴趣的:(Java学习,java,开发语言)