关键词定义:抽象类abstract class,接口interface
成员修饰符:抽象类可以是任意类型,接口只能是默认public static final
方法修饰符:抽象类任意类型,接口默认是public不可以用其他修饰
方法实现:抽象类可以有构造方法,抽象方法和具体实现方法,可以有静态代码块,接口只能抽象方法,没有静态代码块和静态方法
继承方式:抽象类单继承,接口可以实现多个
实现方法:抽象类继承子类不是抽象类需要实现抽象方法,接口需要实现所有的抽象方法
效率:抽象类访问速度比接口速度要快,因为接口需要时间去寻找在类中具体实现的方法;
选择方式:子类都有方法写在抽象类中,即相同的方法封装。子类需要拓展的方法写的接口中,具体的实现类单独去实现接口,可降低耦合度。
final:可以修饰类、方法、成员
final修饰的类不可以被继承,修饰的方法不能被重写,修饰的成员需要赋值不能被改变,但是成员如果是引用类型那么他将不能引用别的对象,但是其内部的属性值是可以被改变的。
static:可以修饰类、方法、成员
static修饰内部类这样就不用实现外部类是创建内部类了,static修饰方法这样可以是直接用类.方法来调用,static修饰成员和方法是一样的类.成员获取或者赋值synchronized:方法、方法块
synchronized修饰方法,同一时刻只能一个线程进行访问,其他线程会被阻塞直到线程锁被释放。synchronized修饰的代码块也差不多,只是可以使用类锁,如果时类锁方法需要改为静态方法。
String为字符串常量,被创建后无法修改,是线程安全的;因为是final修饰所以不能被继承;String的长度不变,适用于少量操作的字符串
StringBuffer是字符串变量,长度可变,线程安全,适用与多线程下大量字符串操作
StringBuilder是字符串变量,长度可变,线程不安全,适用与单线程下大量字符串操作
字符串操作在执行速度:StringBuilder > StringBuffer > String
==:基本数据类型可以比较值是否相等,如果是引用类型则比较的是地址而不是值。
equals:比较的引用类型中堆内存中真正的值是否相同,但是需要重写equals方法
hashCode:hashCode对比实际上会出现不准确的问题,不同的对象可能hash值是一样的,就是hash冲突。因为equals计算较慢,所以在对比对象的时候首先判断hashCode是否一致,不一致的话就是两个对象不相等,如果一致在去判断equals。
克隆:将A实例重新克隆到B实例
浅克隆:将A中的基本数据类型进行值传递,引用类型进行引用传递,2个引用指向同一个堆内存
神克隆:将A中的基本数据类型进行值传递,引用类型复制一份全新的对象,2个引用指向不同的堆内存
Error:是系统性错误,不可以预料的。程序遇到error会直接崩溃,只能排查代码修复
Exception:是异常,可以预料的,可以通过try cacth去捕获或者抛出。异常分为2种,运行时异常和编译时异常,运行时异常忽略异常捕获,编译时异常必须try cacth捕获
java中的反射机制,是程序运行的时候可以获取和使用到某个类中的所有成员和方法。
应用场景:eventBus框架、Gson框架、Retrofit框架、逆向编程
Object中,equals代表的是==,即地址相同,同样hashCode的计算也是代表地址的hash值。
比如我们自定义A类。这个时候重写了equals我们可以判断他的地址也可以判断他的值,但是如果不重写hashCode方法,某认的hashCode和我们equals代表的含义就不同了默认是object里面的hashCode,计算的是地址。java原则上equals相同的则代表2个对象的hashCode一定相同。
在使用HashMap的时候,例如put或者remove的时候,会判断对象的hashCode、地址和equals联合使用判断对象是否相同。这个时候如果hashCode跟equals不一致则会出现数据问题。
字节流
InputStream(字节输入流)->FileInputStream:read()
OutputStream(字节输出流)->FileOutputStream:write()
字符流
Reader(字符输入流)->FileReader:fileReader()
Writer(字符输出流)->FileWriter:fileWriter()
缓冲流
字节
InputStream->FileInputStream->BufferedFileInputStream
OutputStream->FileOutputStream->BufferedFileOutputStream
字符
Reader->FileReader->BufferedReader
Reader->InputStreamReader(字符转换输入流)字节转字符
Writer->FileWriter->BufferedWriter
Writer->OutputStreamWriter(字符转换输出流)字节转字符
对象流
ObjectInputStream(对象输入流)
ObjectOutputStream(对象输出流)
打印流
PrintStream
备注:纯文本用字符流,mp3、word或者其他文件类型用字节流
擦边就是在编译的时候,所有的泛型会被去掉,默认继承Object
解决的局限:1、ArrayList
加入Integter会编译报错 2、ArrayList 取值的时候会出现类型强转Object->String 3、父类定义泛型,子类实际实现的是重写(不是重载),通过编译器的桥方式 未解决:1、泛型无法是基本数据类型 2、运行时无法知道类型 3、泛型类型(T)无法在静态方法和变量中使用
1、常量池问题
字符串创建的时候,如果常量池中被创建了则不会再次被创建,新的引用直接指向已经创建好的。如果说这个值可以被修改,那么其他地方引用可能会出错,所以要保证字符串的唯一性。这也是常量池的优化手段
2、String可以缓存hash值
String的hash值可能被频繁使用,比如HashMap中,如果String不变这样就可以保证Hash值的准确性可以放心缓存,把hash值缓存下来就不需要频繁的生成了也是一种优化策略
3、安全性问题
String通常会代表网球URL或者文件地址等等,如果String变化则不能保证安全性
注解:就是一个标识,对代码规范和变量上面打一个标识,注解大概分为3种
source:针对java文件,生成class文件后消失,主要是对代码规范的约束照规范写代码,比如override注解
class:在编译过程中注解生成class文件,跟java生成class文件效率差不多。常见框架butterKnife和ARouter
RunTime:在class文件生成后还是以注解的形式存在,在运行的时候生效,在代码运行的时候通过反编译进行辅助工作,框架xUtils
成员变量:存在堆中,随着类对象创建而创建,随着类对象销毁而销毁
静态变量:存在方法区,方法区JVM的一部分。随着类的加载而创建,随着类的回收而回收,但是类只有长时间不使用不关联才有可能被回收,所以静态变量的生命周期特别长几乎不会被回收,因此建议不是共享的变量不要用静态的
局部变量:存在堆中,方法执行的时候创建,执行完标记为可回收