java基础核心总结
java的基本语法
数据类型
1 | byte,short,int,long, 1byte = 8bits 1short = 16bits 1int = 32bits 1long = 64bits |
基本语法
1 | 大小写敏感: |
运算符
1 | 赋值运算符: =。 int a = 5; |
java执行控制流程
条件语句
if 条件语句
1 | int a = 10; |
if…else条件语句
1 | int a = 10; |
if…else if 多分支语句
1 | int x = 40; if(x > 60) { |
switch 多分支语句
1 | switch (week) { |
循环语句
1 | while(布尔值){ |
do…while循环
1 | int b = 20; |
for循环语句
1 | for(初始化; 布尔表达式 ; 步进){} |
for-each 语句
1 | int array[] = {7,8,9}; |
跳转语句
break,continue,return
面向对象
属性和方法
属性也称为字段
方法表示 做某些事情的方式,方法的基本组成包括 方法名称、参数、返回值、方法体
方法重载
有参和无参构造函数属于重载的一种,还有一种是,每个重载的方法都有独一无二的参数列表,其中包括参数的类型、顺序、参数数量等,满足重载的条件如下:
- 方法名称必须相同
- 参数列表必须不同(个数不同、类型不同、参数类型排列顺序不同等)
- 方法的返回类型可以相同也可以不相同
- 仅仅返回类型不同不足矣成为方法的重载
- 重载是发生在编译时的,因为编译器可以根据参数的类型来选择使用哪个方法;
方法的重写
重写的原则:
- 重写的方法必须要和父类保持一致,包括返回值类型,方法名,参数列表 也都一样
- 重写的方法可以使用 @Override 注解来标识
- 子类中重写方法的访问权限不能低于父类中方法的访问权限
初始化
类的初始化
使用new 关键字创建对象,等调用构造方法进行初始化
成员初始化
java会尽量保证每个变量在使用前都会获得初始化,分为两种:
编译器默认指定的字段初始化,基本数据类型的初始化
一种是其他对象类型的初始化,String也是一种对象,默认初始值为null,其中也包括基本类型的包装类。
一种是指定数值的初始化,如: int a = 11
构造器初始化
可以利用构造器来对某些方法和某些动作进行初始化,确定初始值
初始化顺序
有如下初始化:
- 静态属性: static开头定义的属性
- 静态方法快: static{}包起来的代码块
- 普通属性:非static定义的属性
- 普通方法块:{} 包起来的代码块
- 构造函数:类名相同的方法
- 方法: 普通方法
1 | public class LifeCycle { |
数组初始化
数组的定义
1 | int[] a1; |
- 直接给每个元素赋值:int array[4] = {1,2,3,4};
- 给一部分赋值,后面的都为0: int array[4] = {1,2};
- 由赋值参数个数决定数组的个数: int array[] = {1,2};
可变参数列表
java中一种数组冷门的用法就是可变参数:
1 | public int add(int... numbers) { |
调用如下:
1 | add(); //不传参数 |
对象销毁
在java中我们不需要手动管理对象的销毁,都是由java虚拟机进行管理和销毁
对象作用域
作用域决定了其内部定义的变量名的可见性和生命周期
this和super
this表示的当前对象,this可以调用方法、属性和指向对象本身。
this还可以和构造函数一起使用,充当一个全局关键字的效果
1 | public class Apple { |
this(参数)相当于调用了其他构造方法,然后传递参数进去。注意:::this()必须放在构造方法的第一行,否则编译失败;
如果把this理解成指向自身的一个引用,那么super就是指向父类的一个引用。super和this一样,可以使用 super.对象 来引用父类的成员。也可以使用super(参数) 来调用父类的构造函数。
封装( 访问控制权限)
访问控制权限又称为 封装,
访问控制权限的核心: 只对需要的类可见。
java中成员的访问权限共有四种 : public、protected、default、private
private | default | protected | public | |
---|---|---|---|---|
同一类 | ✅ | ✅ | ✅ | ✅ |
同一包中的类 | ✅ | ✅ | ✅ | |
子类 | ✅ | ✅ | ||
其他包中的类 | ✅ |
继承
只要我们创建一个类,就隐式继承自Object父类,只不过没有指定。如果你显示指定了父类,那么你继承于父类,而你的父类继承于Object类。
继承的关键字: extends
子类可以重写父类的方法,也可以直接使用父类的方法
多态
多态指的是同一个行为具有多个不同表现形式。
多态的实现,需要三种充要条件:
- 继承
- 重写父类的方法
- 父类引用指向子类对象
接口和抽象类
接口
接口相当于就是对外的一种约定和标准
接口的关键字:interface
特征:
interface
接口是一个完全抽象的类,会进行方法的定义接口中只能使用两种访问修饰符,一种是public,他对整个项目可见,一种是 default 缺省值,只具有包访问权限
接口只提供方法的定义,接口没有实现,但是接口可以被其他类实现。
即:实现接口的类需要提供方法的实现,实现接口使用
implements
关键字来表示,一个接口可以有多个实现接口不能被序列化,所以接口中不能有任何构造方法,
接口的实现比如实现接口的全部方法,否则必须定义为 抽象类 ,
抽象类
抽象类的关键字: abstract
特征:
- 如果一个类中有抽象方法,那么这个类一定是抽象类,也就是说,使用关键字 abstract修饰的方法一定是抽象方法,具有抽象方法的类一定是抽象类。实现类中只有方法具体的实现。
- 抽象类中不一定只有抽象的方法,抽象类中也可以有具体的方法,可以自己选择是否实现
- 抽象类中可以定义:构造方法、抽象方法、普通属性、方法、静态属性和静态方法
- 抽象类和接口一样不能被实力化,实例化只能实例化 具体的类。
异常
java.lang.Exception 是一个顶级接口,继承于Throwable类,
Throwable
Throwable类是java语言中所有错误(errors)和异常(exceptions)的父类。只有继承于Throwable的类或者其子类才能够被抛出,还有一种方式是带有java中的@throw注解的类也可以抛出。
常用的Exception
Exception有两种异常:一、RuntimeException;二、CheckedException。这两种异常都应该去 捕获。
RuntimeException:
序号 | 异常名称 | 异常描述 |
---|---|---|
1 | ArrayIndexOutOfBoundsException | 数组越界异常 |
2 | NullPointerException | 空指针异常 |
3 | IllegalArgumentException | 非法参数异常 |
4 | NegativeArraySizeException | 数组长度为负异常 |
5 | IllegalStateException | 非法状态异常 |
6 | ClassCastException | 类型转换异常 |
UncheckedException:
序号 | 异常名称 | 异常描述 |
---|---|---|
1 | NoSuchFieldException | 表示该类没有指定名称抛出来的异常 |
2 | NoSuchMethodException | 表示该类没有指定方法抛出来的异常 |
3 | IllegalAccessException | 不允许访问某个类的异常 |
4 | ClassNotFoundException | 类没有找到抛出异常 |
与Exception有关的java关键字
throws、throw、try、finally、catch
什么是error
Error 是程序无法处理的错误,表示运行应用程序中较严重问题。 比如:OutOfMemoryError和StackOverflowError异常。
内部类
可以将一个类的定义放在另一个类的内部,这就是内部类
内部类拥有外部类的访问权限。
局部内部类:定义在方法和作用域内部
定义内部类的方式:
- 一个在方法中定义的类(局部内部类)
- 一个定义在作用域内的类,这个作用域在方法的内部(成员内部类)
- 一个实现了接口的匿名类(匿名内部类)
- 一个匿名类,它拓展了非默认构造器的类
- 一个匿名类,执行字段初始化操作
- 一个匿名类,它通过实例初始化实现构造
集合
Iterable接口
实现此接口允许对象成为for-each循环的目标,也就是增强for循环,它是java中的一种语法糖。
除了实现此接口的对象外,数组也可以用for-each循环遍历
顶级接口
Collection是一个顶层接口,他主要用来定义集合的约定
List也是一个顶层接口,它继承了Collection接口,同时也是ArrayList、LinkedList等集合元素的父类
Set接口位于与List接口同级的层次上,它同时继承了Collection接口,Set接口提供了额外的规定,它对add、equals、hashCode方法提供了额外的标准。
Queue是和List、Set接口并列的Collection的三大接口之一。即队列
SortedSet接口直接继承于Set接口,使用Comparable对元素进行自然排序或者使用Comparator在创建时对元素提供定制的排序规则。set的迭代器将按生序元素顺序遍历集合。
Map是一个支持key-value存储的对象,Map不能包含重复的key,每个键最多映射一个值。这个接口代替了dirctionary类,Dictionary是一个接口类而不是接口。
ArrayList
ArrayList是实现了List接口的 可扩容数组(动态数组),它的内部是基于数组实现的。
- ArrayList不是线程安全的容器,作为替代条件可以使用线程安全的List,应使用Collections.synchronizedList
- ArrayList可以实现所有可选择的列表操作,允许所有的元素,包括空值。
- ArrayList有一个容量的概念,这个数组的容量就是List用来存储元素的容量。
- ArrayList具有fail-fast快速失败机制,能够对ArrayList作出失败检测。如迭代集合过程中集合结构发生改变会抛出ConcurrentModificaitoinException异常
Vector
同ArrayList一样,都是基于数组实现的,只不过Vector是一个线程安全的容器,他对内部的每个方法都简单粗暴的上锁,避免多线程引起的安全性问题,但需要的开销较大,因此效率较低。
ArrayList扩容后的数组长度会增加50%,而Vector的扩容后长度数组会增加一倍。
LinkedList类
LinkedList是一个双向链表,允许存储任何元素(包括null),特性如下:
LinkedList所有的操作都可以表现成双向性的,索引到链表的操作将遍历从头到尾,视那个距离近为遍历顺序
LinkedList也不是线程安全的。如果多个线程并发访问链表,并且至少其中的一个线程修改了链表的结构,那么这个链表必须进行外部加锁。或者使用
1
List list = Collections.synchronizedList(new LinkedList(...))
Stack
堆栈是我们常说的 后入先出 的容器。它继承了Vector类,提供了通常用的push和pop操作,以及在栈顶的peek方法,测试stack是否为空的empty方法,和一个寻找与栈顶距离的search方法。
第一次创建栈,不包含任何元素。一个更完善,可靠性更强的LIFO栈操作由Deque接口和它的实现提供,应该优先使用这个类
1 | Deque<Integer> stack = new ArrayDeque<Integer>() |
HashSet
HashSet是Set接口的实现类。不保证元素的迭代顺序,也不是线程安全的,允许null元素
TreeSet
TreeSet是一个基于TreeMap的NavigableSet实现。
LinkedHashSet类
LinkedHashSet是Set接口的Hash表和LinkedList的实现。
HashMap
HashMap是一个利用哈希表原理来存储元素的集合,并且允许空的key-value键值对。HashMap是非线程安全的,而HashTable是线程安全的容器。
HashMap的实例有两个参数影响其性能:初始容量和加载因子。
LinkedHashMap类
LinkedHashMap类是Map接口的哈希表和链表的实现。与HashMap不同之处在于它维护了一个贯穿其所有条目的双向链表。这个链表定义了遍历顺序,通常是插入map中的顺序。
泛型
泛型其实就是一种参数化的集合,它限制了你添加进集合的类型。泛型的本质就是一种参数化类型。
反射
Java 反射机制是在程序的运行过程中,对于任何一个类,都能够知道它的所有属性和方法;对于任意一个对象,都能够知道调用它的任意属性和方法,这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
Class类
在java中,每定义一个java class 实体都会产生一个Class对象,也就是说,当我们编写一个类,编译完成后,在生成的 .class 文件中,就会产生一个Class对象,这个Class对象用于表示这个类的类型信息。Class中没有公共的构造器,也就是说Class对象不能被实例化。
ClassLoader类
反射中,ClassLoader类也非常重要。类装载器是用来把 类(class) 装载进 JVM的。 ClassLoader使用的是双亲委派模型来搜索加载类的,这个模型也就是双亲委派模型。
枚举
在Java中,枚举使用 enum 关键字来表示,枚举其实是一项非常有用的特性。
1 | public enum Family { |