Java学习笔记二
来源:互联网 发布:cs1.6 for mac 编辑:程序博客网 时间:2024/06/06 01:23
后面书中的内容,把图形编程,还有数据库这些都是略过去了,毕竟目前还要以C++为主,去做Qt,后面的线程文件这些东西,并没有写太多东西,因为之前在学的还不错,那些东西都明白知道,而且那些东西记忆性太强,必须通过长时间的实践才会掌握,以后用的时候再去熟练使用吧。网络编程这个就先放下了,等之后去实践做东西的时候,再去系统学学;
小亚~~~~~ 么么哒哒哒哒哒
Java的异常机制主要依赖于try、catch、finally、throw和throws五个关键字;其中try块里面放置可能引发异常的代码块。catch紧跟一个异常的类型和一个代码块,用于表明该catch块用于处理这种异常类型的。多个catch块后还可以跟一个finally块,finally块用于回收try块里打开的物理资源。异常机制保证finally块总会被执行。 throws关键字主要在方法签名中使用,用于声明该方法可能抛出的异常,而throw用于抛出一个实际的异常。
当Java运行时环境受到异常对象时,会寻找能处理该异常对象的catch块,如果找到合适的catch快,就把异常对象交给catch块处理,这个过程叫 捕获异常; 如果找不到捕获异常的catch块,那么程序也将退出。
不管程序代码块是否处于try块中,只要执行这段代码的时候出现了异常,系统都会自动生成一个异常对象。如果没有定义处理这个异常对象的catch块,程序肯定在此处退出。
try块与if语句不一样,try块后面的花括号({…})不能省略,catch的也是一样的。
Java提供了丰富的异常类,并且这些异常之间有严格的继承关系。继承关系如下:
从上面可以看出,异常分为两种:异常(Exception)和错误(Error),都是继承Throwable父类。
Error错误,一般是指虚拟机相关的问题,如系统崩溃、虚拟机处错误、动态连接失败等,这种错误没法回复或不可能捕获,将导致程序中断。应用程序无法处理这些错误,因此应用程序不应该试图使用catch块来捕获Error对象。所以无须在其throws子句中声明该方法可能抛出Error及其任何子类。
public class TestNull{ public static void main(String[] args) { Date d = null; try { System.out.println(d.after(new Date)); } catch(NullPointerException ne) { System.out.println("空指针异常"); } //注意一定要把Exception放到最后面 catch(Exception e) { System.out.println("位置异常"); } }}
注意上面的程序中,我们把Exception类的catch总是放在最后,为什么呢?我想应该明白吧,因为如果把Exception放在前面的话,那么他后面的catch块就没有作用了。实际上,我们不仅应该吧Exception的catch块放在最后,所有父类的异常的catch块都应该排在子类异常的后面。
try{ statements...}catch(RuntimeException e){ System.out.println("运行时异常");}//注意一定要把Exception放到最后面catch(NullPointerException ne){ System.out.println("空指针异常");}
如果按上面的程序进行编译,但是由于第一个RuntimeException是后面的异常的父类,所以第二个异常永远都没有用了,所以编译会出错。
所以一定要记住先捕获小的异常,再捕获大的异常。
如果程序需要在某个catch块中访问异常对象的相关信息,对于所有的异常对象都包含了如下几个常用方法:
getMessage();//返回该异常的详细描述字符串
printStackTrave();//该异常的跟踪栈信息输出到标准错误输出
printStackTrace(PrintStream s);//将该异常的跟踪栈信息输出到指定输出流
getStackTrace();//返回该异常的跟踪栈信息
如下面的程序实例:
public class TestNull{ public static void main(String[] args) { try { FileInputStream fis = new FileInputStream("a.txt"); } catch(IOException ioe) { System.out.println(ioe.getMessage()); ioe.printStackTrace(); } }}
有些时候,程序在try块中打开了一些物力资源,这些物理资源必须显示回收。所以出现了finally块。
try{ //业务代码}catch(SubExveption e){ //异常处理块}finally{ //资源回收快}
异常处理的语法中,只有try块必须的,后面的catch块和finally块都是可选的;finally块必须位于catch块之后。
try{ fis = new FileInputStream("a.txt");}catch(SubExveption e){ //异常处理块}finally{ if( fis != null ) { try { fis.close(); } catch(IOException ioe) { ioe.printStackTrace(); return; } } System.out.println("程序执行了finally里的资源");}
虽然catch块中有return语句,但是不会强制这个方法结束,一定会先执行finllay块里的代码,再结束程序。
正常的情况下,不要再finally块中使用return或者throw等导致方法终止的语句,一旦在finally块中使用return 或 throw语句,将会导致try块、catch块中的return、throw语句失败。
(到现在我还没太弄明白这两类有什么区别)Java异常被分为两大类:Checked异常和Runtime异常。Check异常如果在程序中没有完善处理根本不会执行。处理方式有两种:
1:如果知道如何处理异常,程序应该使用try,catch来捕获异常。
2:当前不知道如何处理的话,应该在定义该方法时声明抛出该异常。
Runtime异常无须显示声明抛出,如果要捕捉也可以使用try..catch来捕捉异常。
关于Checked异常和Runtime异常的区别:
Checked异常必须被显式地捕获或者传递,如Basic try-catch-finally Exception Handling一文中所说。而unchecked异常则可以不必捕获或抛出。
Checked异常继承java.lang.Exception类。Unchecked异常继承自java.lang.RuntimeException类。
Checked和unchecked异常从功能的角度来讲是等价的。可以用checked异常实现的功能必然也可以用unchecked异常实现,反之亦然。
使用throws声明抛出异常的思路是:当前方法不知道应该如何处理这种类型异常,该异常应该由上一级调用者处理,如果main方法也不知道应该如何处理这种类型的异常,也可以使用throws声明抛出的异常,该异常将交给JVM.JVM对异常处理的方法是:打印异常跟踪栈信息,并终止程序运行。
throws声明只能在方法签名中使用,throws可以声明抛出多个异常类,多个异常类之间以都好隔开。
如果某段代码调用了一个带throws声明的方法,该方法声明跑出了Checked异常,这表明该方法希望它的调用者来处理异常,也就是说,这段代码要么放在try块中显示捕获异常,要么这段代码处于另一个带throws声明抛出的方法中。
public class Test{ //注意两个调用关系以及抛出的异常对象的关系 //最终抛出的异常的对象必须是上一级抛出异常的 //父类,要么是同一级 public static void main(String[] args)throws Exception { Func(); } public static void Func() throws IOException { //因为下面的可能会抛出异常 //所以下面的代码要么在try..catch块中 //要么处于另一个带throws声明的方法中 FileInputStream fis = new FileInputStream("a.txt"); }}
throws可以单独使用,但是throw不能,throw要么和try-catch-finally语句配套使用,要么与throws配套使用;throws出现在方法函数头;而throw出现在函数体;
throw语句抛出的不是异常类,而是一个异常实例,并且每次只能抛出一个异常实例。
throw语句的语法格式如下:
throw ExceptionInstance
用户可以自定义异常都应该继承Exception基类,例如希望自定义Runtime异常,则应该继承RuntimeException基类。定义异常类时通常需要提供两种构造器:一个是无参数的构造器;另一个是带一个字符串的构造器,这个字符串将作为该异常对象的详细说明。
下面是自定义的异常类:
//如果自定义Runtime异常,只需要将继承的Exception类改成//RuntimeException基类public class AuctionException extends Exception{ public AuctionException() {} public AuctionException(String msg) { //通过super调用父类的构造器 super(msg); }}
第十一章
所有和AWT编程相关的类都放在java.awt包和它的子包里,AWT编程中有两个基类:Component和MenuComponent。如下图所提供的图形组件之间的继承关系:
其中Component代表一个能以图形化方式显示出来,并可与用户交互的对象,例如Button按钮,TextField等,而MenuComponent则代表图形界面的菜单组件,包括MenuBar(菜单条)、MenuItem(菜单项)等子类。
Component类有如下几个常用方法设置组件的大小、位置和可见性等。
setLocation(int x,int y);设置组件位置
setSize(int width, int height);设置组件的大小
setBounds(int x, int y, int width, int height);同时设置组件的位置、大小。
setVisible(Boolean b);设置该组件的可见性。‘
布局管理器:
1:FlowLayout布局管理器:
组件像流水一样向某方法六栋(排列),遇到障碍(边界)就折回,重头开始排列。默认情况下,FlowLayout布局管理器从左向右排列所有组件,遇到边间就会折回下一行重新开始。
FlowLayout();使用默认对其方式、默认垂直方式、水平间距创建FlowLayout布局管理器。
FlowLayout(int align);使用指定对齐方式、默认垂直、水平间距创建FlowLayout布局管理器。
lowLayout(int align, int hgap, int vgap);使用指定对齐方式、指定垂直、水平间距创建;
BorderLayout布局管理器:
将容器分为EAST、SOUTH、 WEST、NORTH、CENTER五个区域,普通组件可以放在这五个区域的任意一个。当使用这种布局管理器的时候,需要制定要添加到哪个区域里,如果没有制定添加到哪个区域里,则默认添加到中间区域里。
如果向同一个区域中添加多个组件时,后放入的组件会覆盖前面的组件。
GridLayout布局管理器:
GirdLayout布局管理器将容器分割成纵横线分割的网络,每个网络所占的区域大小相同。当想使用GiridLayout添加组件时,默认从左向右,从上向下。与FlowLayout不同的是,放在GridLayout布局管理器中的各组件的大小由组件所出的区域来决定。
GridBagLayout布局管理器:
这种布局管理器是功能最强大的,但也是最复杂的布局管理器,与GridLayout布局管理器不同的是:GridBagLayout布局管理器中,一个组件可以跨越一个或多个网格,并可以设置各网格的大小互不相同。
CardLayout布局管理器
这种布局管理器是以时间而非空间来管理它里面的组件。它将加入容器的所有组件看成一叠卡片,每次只有最上面的那个Componet才可见。
15章 文件
流的分类:
字节流和字符流:字节流操作的最小数据单元是8位的字节,而字符流操作的最小数据单元是16位的字符。
节点流和处理流:
节点流:可以从/向一个特定的IO设备读/写数据的流,成为节点流,节点流常常被称为低级流。
处理流:用于对一个已存在的流进行连接或封装,通过封装后流来实现数据读/写功能。处理流也被称为高级流;
Java的IO流涉及40多个类,这些类都是从4个抽象基类派生出来的;
InputSteam/Reader:所有输入流的基类,前者是字节输入流,后者是字符输入流。
OutputStream/Writer:所有输出的基类,前者是字节输出流,后者是字符输出流。
16章 多线程
Java中有两种方法创建线程:
1:继承Thread类创建线程类
2:实现Runnable接口创建线程类
第一种方法实现步骤如下:
1、定义Thread类的子类,并重写该类的run方法。
2、创建Thread子类的实例
3、线程对象的start方法来启动该线程
class Test extends Thread{ private int i; public void run() { for(; i<100; i++) //注意下面的getName方法是直接调用的 System.out.println(getName()+" "+i); } public static void main(String[] args) { for(int i=0; i<100; ++i) { System.out.println(Thread.currentThread().getName()+""+i); if(20 == i) { new Test().start(); new Test().start(); } } }}
第二种方法的实现:
1、定义Runable接口的实现类,并重写接口的run方法。
2、创建Runnable实现类的实例,并以此实例作为Thread的target来创建线程对象。
3、调用线程对象的start方法启动线程
class Test implements Runnable{ private int i; public void run() { for(; i<100; i++) //注意下面的getName方法是直接调用的 System.out.println(Thread.currentThread().getName()+" "+i); } public static void main(String[] args) { for(int i=0; i<100; ++i) { System.out.println(Thread.currentThread().getName()+""+i); if(20 == i) { Test st = new Test(); new Thread(st,"新县城1").start(); new Thread(st,"新县城2").start(); } } }}
第二种方法执行的结果两条子线程的i变量是连续的,也就是说这两个子线程是共享i这个变量的!!!
虽然两种方法都可以实现,但是这两种方法还是有区别的:
采用实现Runnable接口方式的多线程:
线程类只是实现了Runnable接口,还可以继承其他类。
在这种方式下,可以多个线程共享同一个target对象,所以非常适合多个线程来处理同一份资源的情况。
劣势:编程复杂些,如果需要访问当前进程,必须使用Thread.currentThread()方法。
采用继承Thread类方式的多线程:
劣势:因为线程类已经继承了Thread类,所以不能再继续继承其他父类。
优势:编写简单,如果需要访问当前线程,无需使用Thead.currentThread()方法。
当发生如下情况下,线程会进入阻塞状态:
1、线程调用sleep方法主动放弃所占用的处理器资源
2、线程调用了一个同步监视器,但该同步监视器正被其他线程所持有。
3、线程调用了一堵塞式IO方法,该方法返回之前,线程被堵塞
4、线程在等待某个通知
5、程序调用了线程的suspend方法将该线程挂起,不过这种方法容易导致死锁。
线程会以以下三种方法之一结束,结束后就处于死亡状态:
1、run()方法执行完成,线程正常结束。
2、线程泡醋一个未捕获的Exception或Error
3、直接调用该线程的stop()方法来结束该线程
为了测试某条线程是否已经死亡,可以调用线程对象的isAlive()方法,当线程处于就绪、运行、阻塞三种状态时,该方法将返回true;当线程处于新建、死亡两种状态时,该方法将返回false。
(绝对不能对一个已经死亡的线程调用start()方法使它重新启动)如果再次调用start()方法来启动线程,将引发ILLegalThreadStateException异常,表明死亡状态的线程无法再次运行。
线程睡眠sleep和线程让步yield的区别在于:线程睡眠是使线程处于堵塞状态,而线程让步是使线程回归到就绪状态
任何线程进入同步代码块、同步方法之前,必须现货的同步监视器的锁定,那么何时会释放对同步监视器的锁定呢?程序无法显示释放对同步监视器的锁定,线程会在如下几种情况下释放对同步监视器的锁定:
1、当前线程的同步方法、同步代码块之行结束,当前线程即释放同步监视器。
2、当线程在同步代码块、同步方法中遇到break、return终止了该代码块、该方法的继续执行,当前线程将会释放同步监视器。
3、当线程在同步代码块、同步方法中出现了未处理的Error或Exception,导致了该代码块、该方法一场结束时会释放同步监视器。
4、当线程执行同步代码块或同步方法时,程序执行了同步监视器对象的wait()方法,则当前线程暂停,并释放同步监视器。
下面情况下,线程不会释放同步监视器:
1、县城执行同步代码块或同步方法时,程序调用Thread.sleep()、Thread.yleld()方法来暂停当前线程的执行,当前线程不会释放同步监视器。
2、线程执行同步代码块时,其他线程调用了该线程的suspend方法将该线程挂起,该线程不会释放同步监视器。
一旦某个线程加入了指定线程组之后,该线程将一直属于该线程组,知道该线程死亡,线程运行中途不能改变它所属的线程组。
- JAVA学习笔记(二)
- JAVA学习笔记二
- Java学习笔记二
- java学习笔记二
- JAVA学习笔记《二》
- Java学习笔记二
- Java学习笔记二
- java学习笔记(二)
- java学习笔记二
- java学习笔记二
- java学习笔记二
- Java学习笔记二
- Java 学习笔记二
- java学习笔记二
- Java学习笔记二
- Java学习笔记二
- JAVA学习笔记二
- java学习笔记二
- 伸展树(Splay tree)学习小结 ---by---cxlove
- (尺取法)poj2100,Graveyard Design
- Android面试之---Android的虚拟机Dalvik 介绍
- Restful实战(基于Jersey)
- WPF学习笔记之-WPF数据绑定
- Java学习笔记二
- opencv实现图像旋转
- Android 事件处理全面剖析
- LCA问题的RMQ做法
- 给出邻边和夹角求面积
- Android资源访问——尺寸资源
- 用安卓自带的原生方法解析从webservice获取的json数据
- LRU Cache
- /etc/fstab 文件解释