一:JAVA简介
1:Java特性:
1:强制面向对象,类之间单继承,但可以实现接口的多继承
2:分布式的
3:健壮的 (强类型机制、异常处理、垃圾自动回收等)
4:安全的
5:可移植的
6:解释型的
7:动态的
2:一个Java文件中,如果有public的类,那么文件的名字和这个类名一致,所有一个文件最多只能有一个public类,也可以一个都没有 main()方法可以在任意一个类中
3:面向对象的特征:
封装、继承、多态、抽象
4:数据类型
原生数据类型:
整型:byte 8位
short 16位
int 32位
long 64位
浮点型:float 32
double 64
字符型:char 16
布尔型:boolean
引用类型:
类
接口
数组
枚举
注解
类型转换:原则1:byte-short -int - long -float-double 浮点型的值默认是double的 (整型的值不存在默认是什么)
原则2;char - int - long - float - double
原则3:char-byte 以及 char-short 一定要强制转换
5:位运算符
& 同时为1才为1 否则为0
~ 0变1 1变0
| 有1就为1
^ 两边不同的时候为1
6:Java内存及回收
栈:存放原生数据类型的变量名和值、存放引用类型的变量名和该引用所指向的对象的首地址
堆:存放引用类型的实例
Java的一个后台线程gc()进行垃圾回收,是虚拟机判断内存不够的时候gc()才进行 所以缺点是不能够精确的进行垃圾回收
7:static关键字:
把对象相关的转换成类相关的,可以修饰属性、方法、代码块、内部类
8:final
不允许改变的
修饰变量:(锁定栈,使栈中的数据不能改变)
变量变成常量 一旦赋值就不能改变(如果是引用类型表示指向的对象不变 但是对象中的内容是可以变的)
赋值方法:初始化时赋值 或者 构造函数中赋值 (如果是static修饰的只能在初始化时赋值)常量没有初始值,所以必须赋值
修饰方法:不能被子类覆盖
修饰类: 不能被继承 final类中的方法也是final的
9:final 、finally 、finalize
final:(最终的 不能改变的)修饰类 变量 方法
finally 异常处理结构的一部分,表示总是执行
finalize 垃圾收集器执行的时候会调用被回收对象的finalize()方法
10:访问权限控制
public 类内部 相同包 子类 其他包
protected 类内部 相同包 子类(其他包中)
默认 类内部 相同包
private 类内部
11:abstract
修饰类和方法
抽象类 一个类继承自一个抽象类 就必须实现抽象类的所有抽象方法(否则也要为抽象类)
抽象方法 抽象方法必须依附抽象类存在,但是抽象类可以有具体方法 可以没有任何抽象方法(女人 男人?)
12:Interface 接口
特殊的抽象类
只能有抽象方法
没有构造方法 不能实例化
接口中的方法都是 public abstract的
接口中的属性都是 public static final的
类是单继承 但类可以实现多个接口(要实现所有的抽象方法,且要声明为public 因为类中默认修饰符是default 而接口中默认就是public)
一个类实现多个接口时 如果变量名冲突,则使用 接口名.变量名 如果方法冲突 只要实现一个就可以了
13:包装类
byte Byte
short Short
Int Integer
long Long
float Float
double Double
char Character
boolean Boolean
14: Object类
hashCode():
同一个对象多次调用 对象的内容没变 ——> 则返回的哈希码值相同
两个对象的内容一样 ——> 则返回的哈希码值相同
哈希码不相同——> 则两个对象的内容不同
==和equals():
==比较的是值相不相等,两个对象做==比较是指:两个引用变量地址是否相同 即是否都指向同一个变量 对于对象来说 equals等价于==
String类型的equals是比较内容,因为创建两个String对象 内存中的地址不同 但是内容可以相同
toString():
返回对象的字符串表示
15:String 、StringBuffer 、StringBulder
池化思想:
把公用资源放到池中,用一个存储区域存放公用资源以减少存储空间的开销
String :
不会改变的字符序列
String s1 = "abc"; //新创建,会在字符串常量池中创建一个“abc"
String s2 = "abc"; //直接把字符串常量池中的”abc“的地址传给s2
String s3 = new String("abc") //直接去堆中创建对象(且该对象不会改变了), 返回地址给s3
字符串连接时 String会产生新的对象 效率低 浪费空间
StringBuffer:
可改变的字符串序列
append()方法在原对象上拼接
可并发操作 且 线程安全
StringBulder
可改变的字符串序列
不支持并发操作 且 非线程安全
16:内部类
定义在类内部的类
分4种:
成员内部类
内部类中不能有任何static变量或方法
依附于外部类,只有先创建了外部类才能创建内部类
局部内部类
定义在方法内
想创建一个类解决问题 但又不希望这个类是公用的
匿名内部类
没有构造方法 因为连名字都没有
静态内部类
创建不依赖外部类
不能访问外部类非静态的成员
使用内部类最吸引人的原因是:每个内部类都能独立的继承一个(接口的)实现,所以无论外部类是否继承了某个(接口的)实现,对内部类都没影响
接口只是解决了部分问题,而内部类使得多重继承的解决方案更加完整
17:overload和override
overload(重载)
方法名称相同,参数的类型或个数不同
对权限没要求
发生在同一个类中
override(重写/覆盖)
方法名称、参数类型、返回值类型全相同
子类的方法不能比父类方法有更加严格的权限 如果父类方法是private 则不存在覆盖,而是相当于子类新加了一个全新的方法
发生在继承关系中
18:抽象类 和 接口
抽象类 接口
可以有构造方法 不能有构造方法
可以有普通成员变量 没有普通成员变量(默认类型是public static final
可以包含普通方法 全都是抽象方法
可以包含静态方法 不能包含静态方法
抽象方法可以是public protected的 全都是public的(默认就是)
一个类继承自一个抽象类 一个类可以实现多个接口
接口更多是在系统架构设计发挥作用
抽象类是在代码实现方面发挥作用,可以实现代码重用
19:进程 线程
进程:操作系统中运行的一个子程序
多进程:操作系统中同时运行多个子程序(提高CPU的使用率)
线程:一个程序中执行的子程序流
多线程:一个程序中执行多个子程序流(提高CPU使用率)
进程的存储空间(堆和栈)是独立的,也就是两个进程之间不相互影响
线程的栈空间独立,堆空间共享 可以相互影响
只有在运行状态的线程才能执行代码
主线程终止(main方法退出)不会影响其他正在运行中的线程
只有当所有线程都终止 进程才会退出
实现线程的两种方式:
1:继承Thread类,覆盖run()方法
2:实现Runable接口,实现run()方法 ,然后要把这个类的对象作为参数传给线程类的构造方法作为参数,之后才能使用
线程生命周期:
1:初始状态:只是处于进程中,没有真正运行
2:可运行状态:调用了start()方法,可以运行,只是在等待CPU的调度
3:运行状态:正在运行的线程,此时它用于CPU的执行权
4:阻塞状态:等待用户输入、sleep()、join()等方法都可以进入 (阻塞状态出来会重新回到可运行状态,等待调度)
5:等待队列状态:线程调用一个对象的wait()方法会放弃该对象的锁标记,进入等待队列状态 (这种状态出来也是会到可运行状态,等待调度)
6:锁池状态:每个对象都有一个互斥锁标记和一个锁池,当一个线程用于一个对象的锁标记后,另一个线程想访问该对象,必须在锁池中等待 (出来也是回到可运行状态)
7:终止状态:一个线程运行结束
锁:
为了防止多线程并发执行造成一个对象的数据不统一,(保持数据的完整性),每个对象都有一个互斥的锁标记和一个锁池,只有在锁池中的线程才能获取对象的锁标记
拥有对象的锁标记的线程才能访问对象
一个线程可以同时拥有多个对象的锁标记,如果锁标记过多,一个线程在等待其他线程放弃锁标记,但是又不释放自己的锁标记供其他线程使用,就会造成死锁
synchronized(同步)
修饰代码块:synchronized(object){...} 对括号内的对象加锁,只有拿到对象锁标记的线程才能执行该代码块
修饰方法:在整个方法范围内对对象加锁,只有拿到对象的锁标记,才能执行该方法
wait():交出锁和CPU的占有
notify():从对象的等待池中移走任意一个线程,并放到锁池中,那里线程一直再等待,直到可以获得对象的锁标记
notifyAll():从对象的等待池中移走索引等待那个对象的线程,并放到锁池中
注意:用notifyAll()取代notify(),因为是系统觉得释放哪个线程
只能对加锁的资源进行wait()和notify()
20:集合框架
集合:保存多个其他对象的对象,不能保存简单类型
List :有序可重复
Set:无序 不可重复
Map:key不可以重复 value可以重复
ArrayList :实质上就是一个会自动增长的数组 查询高效 增删低效
LinkedList :底层采用双向链表实现,查询低效,增删效率高
ArrayList和VecTor都是采用数组方式存储数据,都允许直接按序号索引元素,但是插入元素需要涉及数组元素位移能内存操作,所以查询快而插入慢
VecTor由于使用了synchronized方法(线程安全),通常性能比ArrayList差
LinkedList使用双向链表实现存储,按序号索引需要进行前向或后向遍历,但插入只需要记录本项的前后项即可,所以插入速度较快 LinkedList也是线程不安全的
21:IO
流:流是一个很形象的概念,当程序需要读取数据的时候,会开启一个通往数据源的流,当需要写入数据时 开启一个通往目的地的流,可以想象成数据在其中流动
输入流:InputStream/Reader
输出流:OutputStream/Writer
字节流:InputStream/OutputStream
字符流:Reader/Writer
22:反射
类的类对象 对于任意一个类,在运行状态中,都能够知道这个类的所有属性和方法;对任意一个对象,都能调用他的任意一个方法和属性
这种动态获取信息以及动态调用对象的方法的机智 叫做反射
获取类对象的三种方式
1:Class.forName("类的全路径");
2:类名.class 如:Person.class
3:通过该类对象调用getClass()