美文网首页
java基础知识

java基础知识

作者: 简洁心飞 | 来源:发表于2019-01-16 21:47 被阅读0次
字面值用于表示固定的值(fixed value)
final 修饰的变量 只读、不可修改
final 修饰的方法 不可以被子类的方法重写
final 修饰的类 不能被继承 是功能完整的
final 修饰的变量/方法/类 JVM会对其进行优化、线程安全、
static 修饰的变量 是静态变量、
static 修饰的方法 是静态方法、

final 修饰属性、方法和类,分别表示属性不可变、方法不可覆盖、类不可被继承。
finally 作为异常处理的一部分、只能用在try/catch语句后表示最终一定被执行,经常用于释放资源的情况。
finalize() 是Object类的一个方法、在垃圾回收器执行时会调用被回收对象的finalize()方法、可以覆盖此方法来实现对其他资源的回收、如关闭文件。一旦垃圾回收器准备释放对象占用空间、将首先调用其finalize()方法,在下一次垃圾回收动作发生时、才会真正回收对象占用的内存。
String 字符串、不可变类型、底层使用字符数组存储字符串、该字符数组被final修饰、用作--字符串是常量、字符串字面值、不可变字符序列
StringBuffer 线程安全的可变字符序列、字符串缓冲区、可以改变该序列的长度和内容、可将字符串缓冲区安全地用于多个线程、StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。
StringBuilder 一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。
StringTokenizer 用于分割字符串的工具类
abstract 修饰符、用来创建抽象类和抽象方法
synchronized 修饰方法或代码块同一时间只能被一个线程访问、用于线程同步
volatile 修饰符、主要用于线程的编程
this  用来指代当前实例对象
super 用来访问父类的方法或属性.
运算符优先级:. () [] 、+ - ++ -- ~ !、* / %、+ -、... ?:、= += -= *= /= %=
Class ArrayList<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable

ArrayList是List接口的可调整大小的数组实现。ArrayList是一个动态数组,实现了列表相关的所有方法。
ArrayList除了实现List接口之外,还提供了一些方法来操作内部用于存储列表的数组的大小。
Note that this implementation is not synchronized. 这个类大致相当于Vector,除了它是不同步的。
add方法,在插入元素之前,它会先检查是否需要扩容,然后再把元素添加到数组中最后一个元素的后面
ArrayList创建时的大小为0;当加入第一个元素时,进行第一次扩容时,默认容量大小为10。ArrayList每次扩容为当前数组大小的1.5倍。
ArrayList实现RandomAccess接口,表示ArrayList支持快速随机访问(通常是恒定时间)
class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable

Vector类实现了一个可增长的对象数组。 像数组一样,它包含可以使用整数索引访问的组件。但是,Vector的大小可以根据需要增大或缩小,以适应在创建Vector之后添加和删除项目。
根据源码分析、Vector的方法几乎都被synchronized修饰、所以Vector是线程同步的。 如果不需要线程安全实现,建议使用ArrayList代替Vector。
Vector实现RandomAccess接口,表示Vector支持快速随机访问(通常是恒定时间)
class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable

LinkedList是List接口和Deque接口的双项链表实现。 实现所有列表操作,并允许所有元素(包括null)。
对于双向链表,所有操作都可以预期。列表中的索引操作将从开头或结尾遍历开始列表,以较接近指定索引为准。
请注意,此实现不同步。如果多个线程同时访问链表,并且至少有一个线程在结构上修改了列表,则必须在外部进行同步。结构修改是添加或删除操作;仅设置元素的值不是结构修改。
LinkedList没有实现RandomAccess接口,不支持快速随机访问
LinkedList的存储结构为链式存储结构、插入元素时不需要对数据进行移动、因此插入效率较高。
LinkedList继承AbstractSequentialList抽象类、支持顺序访问元素、
LinkedList实现Deque接口、可以双向索引/操作数据
"ArrayList、LinkedList、Vector"
Vector、ArrayList、LinkedList、 都实现List接口、数据结构均为动态可变数组、允许重复元素。
ArrayList和Vector都是基于存储元素的Object[]array数组来实现的、它们会在内存中开辟一块连续的空间来存储、由于数据存储是连续、因此支持用序号/下标来访问元素、同时索引数据的速度比较快、但是在插入元素时需要移动容器中的元素、所以对数据的插入操作执行得比较慢。
ArrayList和Vector都有一个初始化的容量大小、当里面存储的元素个数超过这个大小时就需要动态地扩充它们的存储空间。为了提高程序的效率、每次扩充容量、不是简单地扩充一个存储单元、而是一次增加多个存储单元。Vector默认扩充为原来的2倍。ArrayList每次扩容为当前数组大小的1.5倍。
ArrayList和Vector的最大区别就是synchronization同步的使用、ArrayList类没有一个方法是同步的、而Vector类的绝大多少方法都是直接或间接同步的、所以Vector是线程安全的、ArrayList不是线程安全的。正是由于Vector提供了线程安全的机制、其性能上也要略逊于ArrayList。
LinkedList类是采用双向列表来实现的、对数据的索引需要从列表头开始遍历、因此用于随机访问则效率比较低、但是插入元素时不需要对数据进行移动、因此插入效率较高。同时LinkedList是非线程安全的容器。
当对数据的主要操作为索引或者只是在集合的末端增加、删除元素时、使用ArrayList或Vector效率比较高
当对数据的操作主要为指定位置的插入或删除操作时、使用LinkedList效率比较高
当在多线程中使用容器时、选用Vector比较安全。
# SortedSet 与 SortedMap 默认的排序是自然序,可通过 Comparator 或 Comparable 接口实现自定义排序
"SortedSet"接口:实现 SortedSet 接口的数据结构默认可按升序打印元素,例如 TreeSet。
"TreeSet":实现 NavigableSet 接口,不允许重复的元素,底层数据结构为红黑树。
"HashSet":实现 Set 接口,不允许重复的元素,底层数据结构为 hash table。
"LinkedHashSet":底层数据结构为哈希表与双链表、实现Set接口/不允许重复的元素,。
"SortedMap"接口:继承了 Map 接口,默认以key升序打印元素, 例如 TreeMap。
"TreeMap":实现 SortedMap 接口,底层数据结构为红黑树。
"HashMap":实现 Map 接口,底层数据结构为 hash table。
"HashTable":实现 Map 接口,底层数据结构为 hash table。
"LinkedHashMap":实现 Map 接口,底层数据结构为 hash table 与双链表。
interface Iterable<T>  实现此接口的对象允许成为“for-each loop”语句的目标,java.lang包中的接口;
interface Collection<E> extends Iterable<E> 集合层次结构中的根接口。 Collection表示一组对象(也称为元素)。;
interface List<E> extends Collection<E> 该接口定义有序集合/序列,列表通常允许重复元素,可以精确控制列表元素的插入位置。;
interface Set<E> extends Collection<E> 不包含重复元素的集合、数学意义上的集合;
interface Queue<E> extends Collection<E> 设计用于在处理之前保持元素的集合。 除了基本的Collection操作外,队列还提供额外的插入,提取和检查操作。队列通常(但不一定)以FIFO(先进先出)方式对元素进行排序;
interface Map<K,V> 定义映射类型的接口、Map不能包含重复的键;每个键最多可以映射一个值。例如 HashMap、LinkedHashMap、Hashtable。
当我们新建一个对象时,Java会在Heap中申请一块内存区域用以存放类的数据。而成员变量就是类的数据,也是放在这块内存区域中的。只需要JVM在申请内存的时候顺便把整块区域都置为零即可完成初始化,方便快捷。
而对于方法的局部变量,是在线程的Stack中,当然Stack他也可以帮我们初始化,不过有一个问题。对于有些局部变量,在方法的一开始是没有的,有些在循环中的局部变量是要反复的声明多次的。有些局部变量作用域结束后,另一个局部变量又会占用这个局部变量的位置。
局部变量运行时被分配在栈中,量大,生命周期短,如果虚拟机给每个局部变量都初始化一下,是一笔很大的开销,但变量不初始化为默认值就使用是不安全的。出于速度和安全性两个方面的综合考虑,解决方案就是虚拟机不初始化,但要求编写者一定要在使用前给变量赋值

"String 类"
 String 类 代表字符串、字符串是常量;它们的值在创建之后不能更改。线程安全、可以共享.
 String 类 具有的方法可用于检查序列的单个字符、比较字符串、搜索字符串、提取子字符串、创建字符串副本并将所有字符全部转换为大写或小写.
"StringBuffer 类"
 线程安全的可变的字符序列. 类似String的字符串缓冲区但可以修改. 在任何时间点它都包含一些特定的字符序列,但序列的长度和内容可以通过某些方法调用来改变.
 StringBuffer可供多个线程使用。这些方法在必要时进行同步,以便任何特定实例上的所有操作都表现得好像它们以某个串行顺序出现,这与所涉及的每个单独线程所进行的方法调用的顺序一致。
 StringBuffer上的主要操作是append和insert方法,它们被重载以接受任何类型的数据。每个都有效地将给定的数据转换为字符串,然后将该字符串的字符追加或插入字符串缓冲区。append方法总是在缓冲区的末尾添加这些字符;insert方法在指定点添加字符
 当发生与源序列有关的操作(如源序列中的追加或插入操作)时,该类只在执行此操作的字符串缓冲区上而不是在源上实现同步
 每个字符串缓冲区都有一定的容量。只要字符串缓冲区所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区数组。如果内部缓冲区溢出,则此容量自动增大。从 JDK 5 开始,为该类补充了一个单个线程使用的等价类,即StringBuilder与该类相比,通常应该优先使用 StringBuilder 类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快.
"StringBuilder 类"
 StringBuilder是一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快
 在 StringBuilder 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串生成器中。append 方法始终将这些字符添加到生成器的末端;而 insert 方法则在指定的点添加字符
 每个字符串生成器都有一定的容量。只要字符串生成器所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区。如果内部缓冲区溢出,则此容量自动增大。
 将 StringBuilder 的实例用于多个线程是不安全的。如果需要这样的同步,则建议使用 [StringBuffer]。

[final]()
final 用于声明属性、方法和类,分别表示属性不可变、方法不可覆盖、类不可被继承。
[finally]()
finally作为异常处理的一部分、只能用在try/catch语句后表示最终一定被执行,经常用于释放资源的情况。
[finalize]()
finalize是Object类的一个方法、在垃圾回收器执行时会调用被回收对象的finalize()方法、可以覆盖此方法来实现对其他资源的回收、如关闭文件。一旦垃圾回收器准备释放对象占用空间、将首先调用其finalize()方法,在下一次垃圾回收动作发生时、才会真正回收对象占用的内存。

[不可变类]()
immutable class 是指当创建类这个类的实例后、就不允许修改它的值了、一旦对象被创建、在整个生命周期中、它的成员变量就不能被修改了。有点类似于常量const.只允许程序读取、不允许进行修改。所有基本类型的包装类都是不可变类、Integer、Float等。String类也是不可变类。
定义不可变类:1.类中所有成员变量被private修饰。2.类中没有修改成员变量的方法、3.确保类中所有方法不会被子类覆盖`static final` 4.如果类成员不可变、那么在成员初始化方法或者get方法获取该变量时, 需要通过clone方法确保类的不可变性。5.如果需要、可覆盖Object类的equals方法和hashCode方法。

[值传递]()
在方法调用中、实参会把它的值传递给形参、形参只是用实参的值初始化一个临时的存储单元,因此形参于实参虽然有相同的值、但却有不同的存储单元, 因此改变形参不影响实参的值。
[引用传递]()
在方法调用中, 传递的是对象的地址、这时形参于实参的对象指向同一块存储单元、因此对形参的修改会影响实参的值。

java中原始数据类型在传递参数时都是按值传递、而包装类型在传递参数时是按引用传递的.



作用一:为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关.
作用二:实现某个方法或属性与类关联在一起、而不是对象关联. 就是说在不创建对象的情况下就可以通过类直接调用方法或使用类的属性。
static使用的4种情况:成员变量、成员方法、代码块、内部类。
static成员变量:静态变量属于类、在内存中只有一个复制、所有实例都指向同一个内存地址、只要静态变量所在的类被加载、这个静态变量就会被分配内存空间。
static成员方法:static方法是类的方法、通过类直接调用、static 方法中不能使用this和super关键字、不能调用非静态方法、不能访问非静态变量。static的一个很重要的用途就是实现单例模式。
static代码块:静态代码块、在类中独立于成员变量和成员方法、不在方法体中、JVM在加载类时会执行static代码块, 如果有多个static代码块、JVM将会按顺序执行。static代码经常用来初始化静态变量。
static内部类:static内部类不依赖于外部类的实例对象而被实例化。而是普通的内部类需要在外部类实例化才能实例化。静态内部类于外部类有相同的名字,不能访问外部类的不同成员变量、只能访问外部类的静态成员、静态方法。
static 于 final 结合使用表示什么?
可以用来修饰成员变量、成员方法、类似C中的全局常量
对于变量、static final 修饰、则表示一旦赋值、不可修改
对于方法、static final 修饰、则表示该方法不可以被覆盖、通过类名直接访问

synchronizedLock
synchronized 和 Lock 两种锁机制实现对共享资源的同步. synchronized使用Object对象本身的notify、wait、notifyAll调度机制. 而Lock可以使用Condition进行线程之间的调度, 完成synchronized实现的所有功能

1>用法不一样:在需要同步的对象中加入synchronized控制, synchronized可以加在 静态方法、实例方法、代码块中。而Lock需要显式的指定起始位置和终止位置。synchronized是托管给JVM执行的,而Lock的锁定是通过代码块实现的,它有比synchronized更精准的线程语义。
2>性能不一样:在JDK5中增加类一个Lock接口的实现类ReentrantLock. 它不仅拥有和synchronized相同的并发性和内存语义, 还多了锁投票、定时锁、等候、中断锁等。他们的性能在不同情况下会有所不同:在资源竞争不是很激烈的情况下, synchronized的性能要优于ReentrantLock, 但是在竞争很激烈的情况下, synchronized的性能会下降的非常快,而ReentrantLock的性能基本保持不变.
3>锁机制不同:synchronized获得锁和释放锁都是在块结构中、当获取多个锁时, 必须以相反的顺序释放, 并且是自动解锁,不会因为出现异常而导致锁没有被释放从而引起死锁问题的发生。而Lock则需要开发人员手动释放, 并且只能在finally块中释放, 否则会引起死锁问题的发生。此外Lock还提供类更强大的功能, 它的tryLock()方法可以采用非阻塞的方式去获取锁。最好不要同时使用它们。
悲观锁:一段执行逻辑加上悲观锁,不同线程同时执行时,只能有一个线程执行,其他的线程在入口处等待,直到锁被释放。
乐观锁:一段执行逻辑加上乐观锁,不同线程同时执行时,可以同时进入执行,在最后更新数据的时候要检查这些数据是否被其他线程修改了(版本和执行初是否相同),没有修改则进行更新,否则放弃本次操作。


java实现C语言中函数指针的功能
通过利用接口和类来实现、先定义一个接口、然后在接口中声明要调用的方法、接着实现这个接口、最后把这个实现类的一个对象作为参数传递给调用程序、调用程序通过这个参数来调用指定的函数、从而实现回调函数的功能。


Java数组
数组的元素类型和数组的大小都是确定的,所以当处理数组元素时候,我们通常使用基本循环或者 foreach 循环。
ArrayList是动态链表、将Array转换成ArrayList可以更方便地进行增删改


序列化 (Serialization)
将对象的状态信息转换为可以存储或传输的形式的过程


volatile 是一个类型修饰符, 设计用来修饰被不同线程访问和修改的变量。被volatile 修饰的变量, 系统每次用它时都是直接从对应的内存当中提取, 而不是利用缓存. 所有线程在任何时候看到的该变量的值都是相同的。由于volatile不能保证操作的原子性, volatile不能代替sychronized。使用volatile会阻止编译器对代码的优化, 会降低系统的执行效率, 尽量不要使用。
volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值

instanceof 是一个二元运算符、判断一个引用类型的变量所指向的对象是否是一个类 (或接口、抽象类、父类)的实例。

strictfp 修饰符、strict float point   精确浮点、确保浮点运算的准确性、用于声明一个类、接口、方法

[面向对象特征]()
抽象、封装、继承、多态
多态:允许不同类的对象同一个消息作出的响应。
封装:封装是隐藏实现细节、只对外提供访问的接口,

[方法重载]()  overload
重载是指同一个类中有多个同名的方法、方法名称相同、参数个数或类型不同。重载可以看作是类中方法的多态性。

方法覆盖 override
子类可以覆盖父类的方法、因此同样的方法会在子类和父类中有不同的表现、子类和父类方法中的实现不同。基类的引用变量不仅可以指向基类的实例、也可以指向其子类的实例对象。接口的引用变量也可以指向其实现类的实例对象。程序调用的方法在运行期才动态绑定。绑定指的是将一个方法调用和一个方法主题连接到一起。方法覆盖实现的多态、称为运行时多态。

方法覆盖、必须方法名称相同、参数个数相同、参数类型相同、返回值类型相同、private方法不能覆盖

覆盖是子类与父类直接的关系、是垂直关系
重载是同一个类中方法之间的关系、是水平关系


抽象类 abstract class
如果一个类中包含抽象方法、这个类就是抽象类。
只要包含一个抽象方法、这个方法的类必须是抽象类。
抽象类可以只有方法声明、没有方法实现、
抽象类不能被实例化、但可以声明一个变量指向具体子类的一个实例。
抽象类的子类为抽象父类中的所有抽象方法都提供了具体的实现
抽象类可以包含部分方法的实现哦。


接口 interface
接口就是指一个方法的集合、接口中的所有的方法都没有方法体. 接口可以看作抽象类的变体、接口中所有方法都是抽象的、可以通过接口间接的实现多重继承.
接口中的变量都是static final类型。

抽象类与接口的比较
接口和抽象类都不能实例化。接口和抽象类中的方法只有被实现和继承的子类实现后才可以实例化。
接口只有方法定义、其方法不能在接口中实现、只有实现接口的类才可以实现方法
抽象类可以定义和实现方法、可其方法也可以在抽象类中被发现。
接口需要用implements实现、抽象类使用extends继承。
接口强调特定功能的实现 has-a关系
抽象类情调所属关系 is-a关系
接口中定义的成员变量默认是 public static final 类型、必须赋值。
接口常用于实现常用的功能、抽象类多用于充当功能类的角色。


内部类
一个类定义在另一个类的内部、在类里面的这个类就是内部类。
内部类看作外部类的一个成员。
静态内部类、成员内部类、局部内部类、匿名内部类。


sychronized

原理:加解锁原理、可重入原理、可见性原理
缺陷:效率低、不够灵活、无法预判是否成功获取到锁

支持一种简单的策略来防止线程干扰和内存一致性错误的同步方法:
如果一个对象对于多个线程可见、则对该对象变量的所有读取和写入都是
通过同步方法完成的。保证同一时刻最多只有一个线程执行该段代码、达到并发安全的目的。是最基本的互斥同步手段

this、自定义对象锁、Class对象锁

Sychronized 修饰 普通方法 静态方法 同步代码块

java 类有很多对象、但只有一个Class对象

面试问题
1.两个线程同时访问一个对象的同步方法
2.两个线程同时访问两个对象的同步方法
3.两个线程的是synchronized的静态方法
4.两个线程同时访问同步方法和非同步方法
5.两个线程同一个对象的不同普通同步方法
6.两个线程同时访问static synchronized方法synchronized方法
7.方法抛出异常后、会释放锁

  1. 一把锁在同一时间只能被一个线程获取、没有拿到锁的线程必须等待.
  2. 每个实例都有对应自己的一把锁、不同实例直接互不影响。
  3. 特殊:如果锁对象是 *.class 或 static synchronized 方法、所有对象公用同一把锁、

可重入性:同一个线程的外层函数获得锁之后、内层函数可以直接再次获取该锁、
好处:避免死锁、提升封装性
同一方法、不同方法、不同类的方法、都支持可重入哦
外层函数、内层函数都被synchronized方法修饰、就支持可重入

不可中断性:一个线程获取了锁、别的线程只能等待释放锁、如果这个线程始终不释放、就一直等待下去。


==、equals、hashCode
== 比较两个变量的值是否相等。
继承自Object类的equals方法、就是用的==进行比较的。但是equals方法可以覆盖实现不同的比较哦
hashCode]()


引用数据类型
引用数据类型涉及两块内存、对象本身占用一块内存(堆内层)、变量也占用一块内存。

String s = new String()
变量s占用一块内存、new String()占用一块内存、
变量s占用内存中存储的数据就是对象占用内存的首地址


相关文章

  • Android 知识梳理目录 - 好吧,这是一个很"干

    一、Java 知识梳理 Java&Android 基础知识梳理(1) - 注解Java&Android 基础知识梳...

  • java基础知识

    title: java基础知识tags: [java基础知识] 位运算符 java种的运算符有 “&”,“|”,“...

  • Java基础知识整理(一)

    1.Java基础知识体系 2.Java技术体系平台 3.Java语言特点与核心机制 1.Java基础知识体系 2....

  • 大话Java持久层

    基础知识储备: Java SE(Java语言【java.lang】、Java集合框架【java.util】) Ja...

  • Android面试题4

    1 Java基础知识。线程,java虚拟机,内存模型等。2 Android基础知识。官方API,常用控件源码,自定...

  • Java 序列化

    title: Java 序列化categories: 后台开发tags: java 基础知识 必备 Java 序列...

  • Java基础知识脑图总结

    Java基础知识脑图总结

  • Android内存泄漏

    文章包括两部分: (1)java内存泄漏基础知识 (2)Android内存泄漏。 一.Java内存泄漏基础知识 1...

  • Java面试知识点汇总

    1.基础知识 【JAVA】JAVA 中的小知识(补充中...) 【JAVA】private、protected 和...

  • JNI 基础知识

    JNI 基础知识 什么是 JNI ? JNI (Java Native Interface) 是 Java 沟通 ...

网友评论

      本文标题:java基础知识

      本文链接:https://www.haomeiwen.com/subject/ttuvdqtx.html