JavaSE2
发布时间:2013-12-17 00:23:40
发布时间:2013-12-17 00:23:40
9/25/13
java异常处理机制:
Throwable:
java中异常的顶级父类:
Error:jvm级别的错误;例如:栈内存溢出;
Exception: 程序级别的错误:可以通过捕获机制来解决;
try语句:
try{ 可能出现异常的代码片段 }
try是发现问题的语句;
catch( Exception_Type e){ 解决问题的代码 }
catch语句是用来捕获try语句中出现的异常并针对该异常进行解决;catch可以出现多次;
throw语句:
throw e;
throw 用来主动抛出某一个异常的实例;
通常遇到以下情况会主动抛出异常;
1. 我们定义的方法在运行过程中出现了错误而这个错误如何解决应该由调用者决定时,我们会将异常抛出;
2. 当我们遇到一个不符合业务逻辑的操作时我们可以把它当做一个异常去处理,而主动抛出;
throws声明:(丑话说前面)
我们定义的方法中可能会出现错误,无论是否为我们主动抛出的,但只要是方法中出现的异常不在方法中处理的,我们通常在声明方法时 同时声明可能会抛出的异常,通知调用者必须捕获;
RuntimeException子类:
finally块
finally{ 代码块 }
重写方法时的异常处理:
若父类方法中通过throws声明了某些异常的抛出,那么:
1. 子类重写时 可以不声明throws
2. 子类重写时可以抛出父类抛出的异常的子类异常;
example:父类:throws RuntimeException
子类:throws NullPointerException
3. 子类重写时可以只抛出父类抛出的个别异常;
但是不能:
1. 子类重写时不能抛出父类方法中没有抛出的额外异常;
2. 子类重写是不能抛出父类方法中抛出的异常的父类异常;
File类:
用于描述操作系统中的一个文件或目录;
通过File 我们可以得知文件的名字 大小 修改时间等信息但是不能读取文件的内容;
获取子项:
createNewFile
删除文件或目录 delete
9/26/13
递归删除文件:
FileFilter
RandomAccessFile
用于读写文件内容的类;
java中的文件模型:数据在硬盘保存的形式:byte by byte;
读写文件实际上就是读写字节;
创建RandomAccessFile
RandomAccessFile( File file , String mode)
mode只支持两个: “rw” “r”
Java IO
输入输出流是相对程序而言:
InputStream: 从外界读取信息;
OutputStream:将程序中的数据发送到外界;
java中的流分为
低级流:节点流 数据的来源与去向明确;
高级流:处理流,过滤流;
高级流不能独立存在,通常是基于一个流进行工作,使用高级流可以简化我们的读写操作;
根据流读写数据的单位通常划分为:
字节流和字符流;
字节流: 以字节为单位读写数据;
字符流: 以字符为单位读写数据;
java io中输入流与输出流的父类;
java.io.InputStream
这是一个抽象类,不能实例化,是所有输入流的父类,其中定义了读取数据的相关方法;
java.io.OutputStream
这是一个抽象类,不能实例化,是所有输出流的父类,其中定义了写出数据的相关方法;
FIS与FOS
FileInputStream:用于读取文件的字节流;
FileOutputStream:用于向文件写数据的字节流;
BIS 与 BOS 具有缓冲功能 是高级流;
BufferedInputStream:缓冲字节输入流
BufferedOutputStream:缓冲字节输出流
用于读写基本类型的数据的
DataInputStream
DataOutputStream
字符流:读写以字符为单位;
字符流的父类:
InputStreamReader:
OutputStreamWriter:
读写数据都是基于字节的,所以字符流都是高级流;
缓冲字符输入输出流
特点:以行 为单位读写字符;
BufferedReader:缓冲字符输入流
BufferedWriter:缓冲字符输出流;
用于读取文本文件的字符流
FileReader
文件字符输入流;
FileWriter:
文件字符输出流;
9/29/13
PrintWriter
带自动刷新的缓冲字符流;
PrintWriter( File file )
常用构造方法:
创建一个像给定文件写数据的PrintWriter该常见方式创建了一个不自动行刷新的流
PrintWriter( OutputStream out);
创建一个不具备自动行刷新的基于给定字节输出流,进行写操作的PrintWriter;
PrintWriter( OutputStream out , boolean autoFlush );
创建一个具备自动行刷新的基于给定字节输出流,进行写操作的PrintWriter;当具有自动行刷新后, 每当我们通过该流写行字符串后都会自动flush()清空缓冲区并做一次写操作;
PrintWriter( Writer w)
Printwriter(Writer w ,boolean autoFlush);
PrintWriter ( String FilePath );
根据给定的文件路径,创建基于该文件进行写操作的PrintWriter;
DataInputStream
DataInputStream
写一个基本类型数据的基本过程;
1. 将一个基本类型数据转换成相应的字节;
2. 将字节有序的写入文件保存;
将程序中的数据转化为对应的字节的过程称之为“序列化”
这里的第一步实际上就是将基本类型数据进行了序列化,我们称之为“基本类型序列化”
第二步中我们将数据写入硬盘座长久保存的过程称之为:“数据持久化”;
将字节转换为类型数据的过程叫“反序列化”;
可以对 对象 进行序列化与反序列化的流;
ObjectInputStream
读取字节并转换为对象的输入流(反序列化);
ObjectOutputStream
将对象转为字节后并写出的流(序列化);
JAVA语言的一个优势:处理多线程比较简单;
一般操作系统都支持同时执行多个程序,那么每个同时运行的程序对操作系统而言称为一个进程,而对于一个程序而言,内部也可能同时运行多个任务,那么每个同时运行的任务称为多线程;
无论是进程还是线程,任务都是并发运行的而不是纯粹的同时运行,同时只是宏观上看。
所谓并发:就是宏观上看到所有任务都在同时运行,但微观上讲每个程序都是走走停停的;
创建线程的步骤:
1:定义一个类,并继承Thread类
Thread类是线程类,其中定义这操作线程的相关方法;
2:重写run()方法,该方法中应该定义的内容就是要并发运行的代码片段;
3:实例化线程并启动;
并发的执行过程:
当一个线程调用了 start()方法时,该线程纳入线程调度机制,得以并发运行。
线程调度机制会分配时间片段,获得时间段的线程被CPU执行,当时间片段耗尽,那么该线程等待,线程调度机制会再次分配时间片段给一个线程。
这里要注意:
时间片段的时间不是完全均匀的,而且所有并发运行的任务获取时间片段的几率也不完全相同,但线程调度机制会尽可能均匀分配;
一个线程获取时间片段的长短,以及被分配的次数是通过程序不可控的
我们尽可能避免线程与其要执行的任务关联性太强;
另一种思路:
任务就是任务,线程就是线程,线程只关心可以并发运行即可,给什么任务就并发运行什么任务;
线程常用的方法:
static void sleep(long time);
让当前线程进入睡眠阻塞time毫秒;当时间消耗完毕后,线程重新回到runnable状态;
void interrupt();
中断线程;
创建线程的方式:
1. 继承Thread类 重写Run方法;
2. 实现Runnable接口,实现Run方法;
Thread.currentThread();获得当前线程对象;
调用该thread对象的getName();获得名字;
三种方式让线程死亡:
run()正常结束;
线程抛出未捕获的exception error;
直接调用该线程的stop()方法;
join:
JavaBean 规范;
1. 必须有无参数构造器;
2. 成员变量不能公有化
3. 对应属性的get和set方法;
4. 实现可序列化接口 Serializiable;
IO流分类;
1. 输入输出流
2. 字节流,字符流;
InputStream Reader
3. 低级流 高级流;
FileInputStream
DataInputStream
ObjectInputStream;
9/30
局部内部类中若要引用该方法的其他局部变量 那么这个变量必须是final的
final void setPriority( int p);
参数的取值范围:1-10;
对应三个常量:
MAX_PRIORITY :10
NORM_PRIORITY :5
MIN_PRIORITY :1
守护线程(后台线程)
当一个进程中的所有前台线程运行完毕后,所有后台线程均要强制结束;
进程结束;
当一个进程中的所有线程结束后,该进程结束;
线程安全问题:
由于多线程访问同一数据时可能出现线程安全问题,我们就需要在访问数据的地方保证同步操作,就是要有先后顺序,不能同时访问;
synchronized 关键字;
当synchronized关键字修饰方法时,该方法变成同步方法,多个线程不能同时执行该方法;
若修饰方法,那么锁对象是当前对象,换句话说就是将this锁上;
当一个类中声明的多个方法均被synchronized修饰,那个这些方法是互斥的,同一时间不可能被同时调用;
若所有的操作均都对方法进行同步,显然效率低下,在方法中,有时只需要部分代码需要同步,这时候我们 只需要同步这部分即可,这样可以提高同步效率;
语法:
synchronized( 同步监视器 ){ }
同步监视器就是要上锁的对象,通常同步监视器(上锁的对象)是this 。
线程安全与不安全的类;
线程安全的
StringBuffer
vector
HashTable
线程不安全:
StringBuilder
List
HashMap
builder.append(“”);不是同步的;
很多应用都需要多个线程,而有些情况当一个线程要完成的工作需要基于另一个线程的工作情况,我们则需要两个线程协调工作;
以下方法是在Object中定义的:
wait() : 在当前线程上等待;
notify(): 通知一个在当前线程上等待的线程运行;
notifyAll(): 通知所有在当前对象上等待的线程回到runnable状态;
10/8/13
java.net.Socket
java.net.ServerSocket
Socket运行在客户端
ServerSocket运行在服务端;
连接方式永远是Socket连接serverSocket;
10/9/13
双缓冲队列:
BlockingDeque接口:
其有几个实现类;
BlockingQueue:规定大小的缓冲队列,其构造方法需要带一个int参数,规定该队列长度,该队列存取元素遵循FIFO;
LinkedBlockingQueue:不定长的缓冲队列。最大值为Integer.MAX_VALUE.存取元素:FIFO;
PriorityBlockingQueue:不定长的缓冲队列,存取元素时不遵循FIFO;由自然排序决定,取的元素
SynchronousQueue:特殊的缓冲队列,存取元素必须交替进行;
线程池:ExecutorService:
Executors.newCachedThreadPool();
可以根据需要创建线程, 并在这些线程空闲时重用他们;
Executor.newFixedThreadPool(int size);
创建一个固定大小的线程池,并在线程空闲的时候重用他们;
Executors.newScheduledThreadPool(int size);
创建一个具有延迟执行任务的线程池;
Executors.newSingleThreadExecutor();
使用单线程方式工作;
反射总结:
加载:
连接:
初始化:
类初始化时机:
1. 创建类的实例;使用new 通过反射 通过反序列化创建实例;
2. 调用类的静态方法;
3. 访问某个类或接口的静态属性,或为该静态属性赋值;
4. 使用反射方式强制创建某个类的Class对象;Class.forName(“Person”);
5. 初始化某个类的子类;
6. 直接使用java.exe来运行某个主类;
当一个类装在到内存中就生成一个java.lang.Class 实例。一旦一个类被载入JVM,同一个类就不会被再次载入,因为每个类都有一个唯一的标识,即其全限定名(包名,类名)
ClassLoader API:
loadClass(String name): 该方法执行步骤:
findClass(String name):根据二进制名称来查找类;
defineClass: 此方法将类的字节码文件读入数组并将其转换为Class对象;
findSystemClass(String name);从本地文件系统找到对应文件并调用defineClass将其转换为类;
getParent();获取父类加载器;
static getSystemClassLoader(),用于返回系统类加载器;
3种方式获得Class对象;
1. Class类的forName()静态方法;
2. 调用类的class属性获取Class对象,如:Person.class 最常用;
3. 调用某个对象的getClass()方法;
Class的方法:
getConstructor()
getMethod(String name);
getFields();
getAnnotations();
getDeclaredClasses();获取Class对象的内部类;
getInterfaces();
getPackage();
getSimpleName();
通过反射生成对象两种方式;
使用Class对象的newInstance()方法;
使用Class对象获取指定的Constructor对象,再调用newInstance();