“java基础知识点”,java基础知识总结 超详细
终极管理员 知识笔记 56阅读
1.java和c
2.编译和解释

3.jre和jdkjvm

简单来说编译型语言是指编译器针对特定的操作系统将源代码一次性翻译成可被该平台执行的机器码解释型语言是指解释器对源程序逐行解释成特定平台的机器码并立即执行。
Java 语言既具有编译型语言的特征也具有解释型语言的特征因为 Java 程序要经过先编译后解释两个步骤由 Java 编写的程序需要先经过编译步骤生成字节码*.class 文件这种字节码必须由 Java 解释器来解释执行。因此我们可以认为 Java 语言编译与解释并存。
1、基本数据类型和包装类
-*/会自动拆箱装箱
Java 基本类型的包装类的大部分都实现了常量池技术即 Byte,Short,Integer,Long,Character,Boolean前面 4 种包装类默认创建了数值[-128127] 的相应类型的缓存数据Character 创建了数值在[0,127]范围的缓存数据Boolean 直接返回 True Or False。如果超出对应范围仍然会去创建新的对象。
2、String, StringBuffer and StringBuilder1、可变性
String 不可变
StringBuffer 和 StringBuilder 可变使用 append 方法在末尾添加新的字符串
2、线程安全
String 不可变是线程安全的
StringBuffer可变长字符串效率低线程安全使用 synchronized 同步
StringBuilder可变长字符串效率高线程不安全
new String(abc)创建几个对象2个或者一个.
String为什么不可变String
类中使用 final 关键字修饰字符数组来保存字符串private final char value[]
所以String
对象是不可变的。而 StringBuilder
与 StringBuffer
都继承自 AbstractStringBuilder
类在 AbstractStringBuilder
中也是使用字符数组保存字符串char[]value
但是没有用 final
关键字修饰所以这两种对象都是可变的。
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[]; /** Cache the hash code for the string */ private int hash; // Default to 0 /** use serialVersionUID from JDK 1.0.2 for interoperability */ private static final long serialVersionUID -6849794470754667710L; ...... }
3、static和final final
1、数据
对于基本类型final 使数值不变
对于引用类型final 使引用不变也就不能引用其它对象但是被引用的对象本身是可以修改的。
final int x 1; //x 值不能变final A y new A(); //y 不能改变引用y.a 1;
2、方法
声明方法不能被子类重写。
private 方法隐式地被指定为 final如果在子类中定义的方法和基类中的一个 private 方法签名相同此时子类的方法不是重写基类方法而是在子类中定义了一个新的方法。
3、类
被 final 声明的类不能被继承。final不能直接修饰接口但是可以修饰接口里面的方法和变量
static1、静态变量
静态变量又称为类变量也就是说这个变量属于类的类所有的实例都共享静态变量可以直接通过类名来访问它。静态变量在内存中只存在一份。
实例变量每创建一个实例就会产生一个实例变量它与该实例同生共死。
2、静态方法
静态方法在类加载的时候就存在了它不依赖于任何实例。所以静态方法必须有实现也就是说它不能是抽象方法。
静态方法中只能访问所属类的静态字段和静态方法方法中不能有 this 和 super 关键字因为这两个关键字与具体对象关联。
3、静态语句块
静态语句块在类初始化时运行一次。
4、静态内部类
非静态内部类依赖于外部类的实例也就是说需要先创建外部类实例才能用这个实例去创建非静态内部类。而静态内部类不需要。
静态内部类不能访问外部类的非静态的变量和方法。
4、equals和hashCode()clone()toString()拷贝a instanceof A:判断对象a是否是类A的实例。如果是返回true如果不是返回false。
clone() 是 Object 的 protected 方法若一个类不显式去重写 clone()那么这个类的实例便不能调用 clone() 方法
5、抽象类和接口抽象类和抽象方法都使用 abstract 关键字进行声明。如果一个类中包含抽象方法那么这个类必须声明为抽象类。抽象类中也可以有普通方法和成员变量也可以没有抽象方法。
抽象类和普通类最大的区别是抽象类不能被实例化只能被继承。
抽象类Abstract Class是一个被声明为抽象的类不能被实例化只能被继承。抽象类可以包含抽象方法和非抽象方法。抽象方法是没有具体实现的方法只有方法签名需要子类去实现。非抽象方法则有具体的实现子类可以直接继承并使用。抽象类可以拥有成员变量和构造方法。通过继承抽象类子类可以获取父类的属性和方法并且必须实现父类的抽象方法。抽象类的主要作用是为了提供一种通用的模板或者基类用于子类的继承和扩展。
接口Interface是一种完全抽象的类它只定义了一组方法的签名而没有任何具体实现。接口中的方法都是抽象方法。接口不能包含成员变量但可以包含常量。类可以实现一个或多个接口并且必须实现接口中定义的所有方法。通过实现接口类可以定义自己的行为规范实现多态性。接口的主要作用是定义一组规范用于不同类的实现实现类可以根据接口的规范来提供具体的实现。
区别
抽象类可以有构造方法而接口不能有构造方法。
一个类只能继承一个抽象类但可以实现多个接口。
抽象类可以包含非抽象方法而接口只能包含抽象方法。
抽象类的目的是为了代码复用和继承而接口的目的是定义规范和实现多态性。
抽象类可以拥有成员变量而接口不能拥有成员变量只能定义常量。
选择使用抽象类还是接口取决于具体的需求和设计目标。如果需要提供一些默认的实现或者共享的代码可以使用抽象类。如果需要定义一组规范让不同的类去实现可以使用接口。在实际开发中常常会同时使用抽象类和接口来实现灵活的设计。
5、继承1.重写和重载
this.func(this)
super.func(this)
this.func(super)
super.func(super)
方法的重写要遵循“两同两小一大”以下内容摘录自《疯狂 Java 讲义》,issue#892
“两同”即方法名相同、形参列表相同
“两小”指的是子类方法返回值类型应比父类方法返回值类型更小或相等子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等
“一大”指的是子类方法的访问权限应比父类方法的访问权限更大或相等。
⭐️ 关于 重写的返回值类型 这里需要额外多说明一下上面的表述不太清晰准确如果方法的返回类型是void和基本数据类型则返回值重写时不可修改。但是如果方法的返回值是引用类型重写时是可以返回该引用类型的子类的。
Java 为什么不能通过返回值判断重载特征签名
2.抽象类
抽象类不能被实例化只能被继承。
非抽象的类要实现接口需要把接口中的方法都加以实现那如果我只想用其中一个方法而又不想重写其它方法该怎么办呢 这个时候我们就需要抽象类了抽象类可以重写接口中的方法并添加自己的方法。
从使用上来看一个类可以实现多个接口但是不能多继承
接口的字段只能是 static 和 final 类型的而抽象类的字段没有这种限制。
接口的成员只能是 public 的Java 8 开始也可定义 default 方法Java 9 之后允许将方法定义为 private而抽象类的成员可以有多种访问权限。
6.反射异常泛型注解反射java.lang.Class 和 java.lang.reflect 一起对反射提供了支持
throw 和 throws区别 throw 表示抛出一个异常类的对象生成异常对象的过程。声明在方法体内。 throws 属于异常处理的一种方式声明在方法的声明处。
try-catch-finally
异常在 Java 中所有的异常都有一个共同的祖先 java.lang
包中的 Throwable
类。Throwable
类有两个重要的子类: Error 和 Exception。
Java的泛型是伪泛型这是因为Java在编译期间所有的泛型信息都会被擦掉正确理解泛型概念的首要前提是理解类型擦除。Java的泛型基本上都是在编译器这个层次上实现的在生成的字节码中是不包含泛型中的类型信息的使用泛型的时候加上类型参数在编译器编译的时候会去掉这个过程成为类型擦除。
注解的本质就是一个继承了 Annotation 接口的接口。
7、面向对象 1.面向对象和面向过程的区别 2.成员变量与局部变量静态方法与实例方法 3.创建一个对象用什么运算符?对象实体与对象引用有何不同?Object obj new Object();
简单的一句话包含了三个动作
主要作用是完成对类对象的初始化工作。
5.在调用子类构造方法之前会先调用父类没有参数的构造方法,其目的是?帮助子类做初始化工作。其目的是确保父类中的实例变量和方法在子类中都能够被正确初始化和使用。
存在继承的情况下初始化顺序为
父类静态变量、静态语句块
子类静态变量、静态语句块
父类实例变量、普通语句块
父类构造函数
子类实例变量、普通语句块
子类构造函数
6.面向对象三大特性封装、继承、多态
关于继承如下 3 点请记住
子类拥有父类对象所有的属性和方法包括私有属性和私有方法但是父类中的私有属性和方法子类是无法访问只是拥有。
子类可以拥有自己属性和方法即子类可以对父类进行扩展。
子类可以用自己的方式实现父类的方法。以后介绍。
多态顾名思义表示一个对象具有多种的状态。具体表现为父类的引用指向子类的实例例如扒灰。
8.1 谈谈你对多态性的理解 ① 实现代码的通用性。 ② Object类中定义的public boolean equals(Object obj){ } JDBC:使用java程序操作(获取数据库连接、CRUD)数据库(MySQL、Oracle、DB2、SQL Server) ③ 抽象类、接口的使用肯定体现了多态性。抽象类、接口不能实例化 8.2 多态是运行时行为。
总结编译看左边运行看右边。
8、序列化和transient
关键字 9、获取用键盘输入常用的两种方法
通过 Scanner通过 BufferedReader
10、BIO,NIO,AIO 有什么区别? 11、BigDecimal应该使用 new BigDecimal(String)
如123.123那么如果使用BigDecimal表示那么他的无标度值为123123他的标度为3。对于 0.1使用无标度 1 和标度 1 进行表示。
12、容器容器主要包括 Collection接口 和 Map接口 两种Collection 存储着对象的集合而 Map 存储着键值对映射表。
1.基本概念和主要实现类 2.ArrayList源码分析
jdk8类似懒汉式实现默认大小10大于size就扩容扩容约1.5倍因为 oldCapacity (oldCapacity >> 1)
。扩容代价很高因为调用Arrays.copyOf()
把原数组整个复制到新数组中。删除操作逐个往前移时间复杂度为 O(N)。
Fail-FastmodCount 用来记录 ArrayList 结构发生变化的次数。结构发生变化是指添加或者删除至少一个元素的所有操作或者是调整内部数组的大小仅仅只是设置元素的值不算结构发生变化。在进行序列化或者迭代等操作时需要比较操作前后 modCount 是否改变如果改变了需要抛出 ConcurrentModificationException。类似乐观锁。
有两个线程线程A线程B其中线程A负责遍历list、线程B修改list。线程A在遍历list过程的某个时候此时expectedModCount modCountN线程B启动同时线程B增加一个元素这是modCount的值发生改变modCount 1 N 1。线程A继续遍历执行next方法时通告checkForComodification方法发现expectedModCount N 而modCount N 1两者不等这时就抛出ConcurrentModificationException 异常从而产生fail-fast机制。
java.util
包下面的所有的集合类都是fail-fast的而java.util.concurrent
包下面的所有的类都是fail-safe的。
fail-safe 任何对集合结构的修改都会在一个复制的集合上进行因此不会抛出ConcurrentModificationException。类似CopyOnWrite机制。
Vector 实现线程安全的方法是在每个方法上使用 synchronized 进行同步。默认长度为 10扩容2倍。
3.CopyOnWriteArrayList读写分离原理。缺点内存占用数据不一致。
4.HashMap高八位为什么右移16位? HashMap 的长度为什么是 2 的幂次方?
y%x等价于y&(x-1)
确定桶下标的最后一步是将 key 的 hash 值对桶个数取模hash % capacity如果能保证 capacity 为 2 的 n 次方那么就可以将这个操作转换为位运算。
jdk7 Entry 类型的数组 tableHashMap 默认大小为 16。Entry 存储着键值对。它包含了四个字段key, value, next, hash第0 个桶存放键为 null 的键值对。使用拉链法来解决冲突头插法扩容两倍capacity、size、threshold 和 load_factor扩容后需要把原来的键值对重新计算桶下标。
HashTable实现线程安全是通过在每个方法前加 synchronized因此效率较低
HashMap
可以存储 null 的 key 和 value但 null 作为键只能有一个null 作为值可以有多个HashTable 不允许有 null 键和 null 值否则会抛出 NullPointerException
。
jdk8尾插法当数组长度大于 64链表长度大于等于 8 时会将链表转换为红黑树。
哈希
static final int hash(Object key) { int h; return (key null) ? 0 : (h key.hashCode()) ^ (h >>> 16); }
5.ConcurrentHashMap
jdk7 分段锁机制segment默认的并发级别为 16也就是说默认创建 16 个 Segment。size 方法先尝试不加锁
jdk8CAS和sychronized在 CAS 操作失败时使用内置锁 synchronized。
6.LinkedHashMapafterNodeAccess()
实现LRU头部存放最近最不常用的节点
afterNodeInsertion()
方法在 put 等操作后执行在 afterNodeInsertion() 方法中当 removeEldestEntry() 方法返回 true 时即链表长度大于规定的最大长度会移除最不常访问的节点也就是链表首部节点 first。
Arrays.asList 得到的集合是不可变的。当使用 Arrays.asList 返回 List 集合时为 ArrayList不过注意的是这里的 ArrayList 和平时使用的 ArrayList 不同这里的 ArrayList 为 Arrays 的一个私有静态内部类如下该类继承自 AbstractList但是没有对 add、remove 方法进行重写在 abstract 中addremove 方法会直接抛出异常但是重写了 set 方法因此可使用 set 方法改变某些索引的值。
15、红黑树红黑树是自平衡的二叉查找树。
1每个结点要么是红的要么是黑的。
2根结点是黑的。
3每个叶结点叶结点即指树尾端NIL指针或NULL结点都是黑的。
4如果一个结点是红的那么它的两个儿子都是黑的。
5对于任意结点而言其到叶结点树尾端NIL指针的每条路径都包含相同数目的黑结点。
二叉查找树Binary Search Tree又二叉搜索树二叉排序树它或者是一棵空树或者是具有下列性质的二叉树 若它的左子树不空则左子树上所有结点的值均小于它的根结点的值 若它的右子树不空则右子树上所有结点的值均大于它的根结点的值 它的左、右子树也分别为二叉排序树。
16、Object obj new Date()对象的引用和创建简单的一句话包含了三个动作
Object obj 在栈内存中创建了一个名为 obj 的 Object 类型引用变量它可以指向 Object 类型的对象实体
new Object() 在堆内存中创建了一个 Object 类型对象实体
最后用一个“”将对象引用 obj 指向对象实体 new Object()。
对象引用就是一个变量有名字我们可以直接访问它存储的是一个地址这个地址指向堆内存中某一个该类型的对象实体
而对象实体没有名字我们只能通过对象引用来间接访问它。
最后只有 new 才会创建对象实体才会在堆内存中开辟新的空间。