JAVA经验小结

来源:互联网 发布:淘客小程序源码 编辑:程序博客网 时间:2024/05/19 19:31

本文链接:http://blog.pfan.cn/xiaoqijun/20682.html

6.8 finalize( )方法
有时当撤消一个对象时,需要完成一些操作。例如,如果一个对象正在处理的是非Java资源,如文件句柄或window字符字体,这时你要确认在一个对象被撤消以前要保证这些资源被释放。为处理这样的状况,Java提供了被称为收尾(finalization)的机制。使用该机制你可以定义一些特殊的操作,这些操作在一个对象将要被垃圾回收程序释放时执行。要给一个类增加收尾(finalizer),你只要定义finalize ( )方法即可。Java回收该类的一个对象时,就会调用这个方法。在finalize ( )方法中,你要指定在一个对象被撤消前必须执行的操作。垃圾回收周期性地运行,检查对象不再被运行状态引用或间接地通过其他对象引用。就在对象被释放之前,Java运行系统调用该对象的finalize( )方法。
finalize()方法的通用格式如下:
protected void finalize( )
{
// finalization code here
}

其中,关键字protected是防止在该类之外定义的代码访问finalize()标识符。该标识符和其他标识符将在第7章中解释。理解finalize( )正好在垃圾回收以前被调用非常重要。例如当一个对象超出了它的作用域时,finalize( )并不被调用。这意味着你不可能知道何时——甚至是否——finalize( )被调用。因此,你的程序应该提供其他的方法来释放由对象使用的系统资源,而不能依靠finalize( )来完成程序的正常操作。注意:如果你熟悉C++,那你知道C++允许你为一个类定义一个撤消函数(destructor),它在对象正好出作用域之前被调用。Java不支持这个想法也不提供撤消函数。finalize( )方法只和撤消函数的功能接近。当你对Java有丰富经验时,你将看到因为Java使用垃圾回收子系统,几乎没有必要使用撤消函数。

出自:
http://java.ccidnet.com/art/3555/20060403/495947_6.html

 

6.9 一个堆栈类
尽管Box类在说明一个类的必要的元素时是有用的,但它实际应用的价值并不大。为了显示出类的真实的功能,本章将用一个更复杂的例子来说明类的强大功能。如果你回忆起在第2章中讲过的面向对象编程的讨论,你就会想起对象编程的最重要的好处之一是对数据和操作该数据的代码的封装。你已经知道,在Java中,就是通过类这样的机制来完成封装性。在创建一个类时,你正在创建一种新的数据类型,不但要定义数据的属性,也要定义操作数据的代码。进一步,方法定义了对该类数据相一致的控制接口。因此,你可以通过类的方法来使用类,而没有必要担心它的实现细节或在类的内部数据实际上是如何被管理的。在某种意义上,一个类像“一台数据引擎”。你可以通过操纵杆来控制使用引擎,而不需要知道引擎内是如何工作的。事实上,既然细节被隐蔽,当需要时,它的内部工作可以被改变。只要你的代码通过类的方法来使用它,内部的细节可以改变而不会对类的外部带来负面影响。
为了看看前面讨论概念的一个实际的应用,让我们开发一个封装的典型例子:堆栈(stack)。堆栈用先进后出的顺序存储数据。堆栈通过两个传统的操作来控制:压栈(push)
和出栈(pop)。在堆栈的上面加入一项,用压栈,从堆栈中取出一项,用出栈。你将看到,将整个堆栈机制封装是很容易的。下面是一个叫做Stack的类,实现整数的堆栈。
// This class defines an integer stack that can hold 10 values.
class Stack {
int stck[] = new int[10];
int tos;
// Initialize top-of-stack
Stack() {
tos = -1;
}
// Push an item onto the stack
void push(int item) {
if(tos==9)
System.out.println("Stack is full.");
else
stck[++tos] = item;
}
// Pop an item from the stack
int pop() {
if(tos < 0) {
System.out.println("Stack underflow.");
return 0;
}
else
return stck[tos--];
}
}
正如你看到的,Stack类定义了两个数据项、三个方法。整数堆栈由数组stck存储。该数组的下标由变量tos控制,该变量总是包含堆栈顶层的下标。Stack()构造函数将tos初始化为-1,它指向一个空堆栈。方法push()将一个项目压入堆栈。为了重新取回压入堆栈的项目,调用pop()。既然存取数据通过push()和pop(),数组中存储堆栈的事实实际上和使用的堆栈不相关。例如,堆栈可以被存储在一个更复杂的数据结构中,例如一个链表,但push()和pop()定义的接口仍然是一样的。下面示例的类TestStack,验证了Stack类。该类产生两个整数堆栈,将一些值存入,然后将它们取出。
class TestStack {
public static void main(String args[]) {
Stack mystack1 = new Stack();
Stack mystack2 = new Stack();
// push some numbers onto the stack
for(int i=0; i<10; i++) mystack1.push(i);
for(int i=10; i<20; i++) mystack2.push(i);
// pop those numbers off the stack
System.out.println("Stack in mystack1:");
for(int i=0; i<10; i++)
System.out.println(mystack1.pop());
System.out.println("Stack in mystack2:");
for(int i=0; i<10; i++)
System.out.println(mystack2.pop());
}
}
该程序产生的输出如下:
Stack in mystack1:
9
8
7
6
5
4
3
2
1
0
Stack in mystack2:
19
18
17
16
15
14
13
12
11
10
你已经看到,每个堆栈中的内容是分离的。关于Stack类的最后一点。正如它现在执行的一样,通过Stack类外面的代码可以改变保存堆栈的数组stck。这样的Stack是开放的,容易误用或损坏。在下一章中,你将会看到如何补救这种情况。

出自:

http://java.ccidnet.com/art/3555/20060403/495947_7.html

方法重载:

当一个重载的方法被调用时,Java在调用方法的参数和方法的自变量之间寻找匹配。但是,这种匹配并不总是精确的。在一些情况下,Java的自动类型转换也适用于重载方法的自变量。例如,看下面的程序:
// Automatic type conversions apply to overloading.
class OverloadDemo {
void test() {
System.out.println("No parameters");
}
// Overload test for two integer parameters.
void test(int a,int b) {
System.out.println("a and b: " + a + " " + b);
}
// overload test for a double parameter
void test(double a) {
System.out.println("Inside test(double) a: " + a);
}
}
class Overload {
public static void main(String args[]) {
OverloadDemo ob = new OverloadDemo();
int i = 88;
ob.test();
ob.test(10,20);
ob.test(i); // this will invoke test(double)
ob.test(123.2); // this will invoke test(double)
}
}
该程序产生如下输出:
No parameters
a and b: 10 20
Inside test(double) a: 88
Inside test(double) a: 123.2
在本例中,OverloadDemo 的这个版本没有定义test(int)。因此当在Overload内带整数参数调用test()时,找不到和它匹配的方法。但是,Java可以自动地将整数转换为double型,这
种转换就可以解决这个问题。因此,在test(int)找不到以后,Java将i扩大到double型,然后调用test(double)。当然,如果定义了test(int),当然先调用test(int)而不会调用test
(double)。
只有在找不到精确匹配时,Java的自动转换才会起作用。

方法重载支持多态性,因为它是Java实现 “一个接口,多个方法”范型的一种方式。要理解这一点,考虑下面这段话:在不支持方法重载的语言中,每个方法必须有一个惟一的名字。但是,你经常希望实现数据类型不同但本质上相同的方法。可以参考绝对值函数的例子。在不支持重载的语言中,通常会含有这个函数的三个及三个以上的版本,每个版本都有一个差别甚微的名字。例如,在C语言中 ,函数abs( )返回整数的绝对值,labs( )返回long型整数的绝对值( ),而fabs( )返回浮点值的绝对值。尽管这三个函数的功能实质上是一样的,但是因为C语言不支持重载,每个函数都要有它自己的名字。这样就使得概念情况复杂许多。尽管每一个函数潜在的概念是相同的,你仍然不得不记住这三个名字。在Java
中就不会发生这种情况,因为所有的绝对值函数可以使用同一个名字。确实,Java的标准的类库包含一个绝对值方法,叫做abs ( )。这个方法被Java的math类重载,用于处理数字类型。Java根据参数类型决定调用的abs()的版本。重载的价值在于它允许相关的方法可以使用同一个名字来访问。因此,abs这个名字代表了它执行的通用动作(general action)。为特定环境选择正确的指定(specific)版本是编译器要做的事情。作为程序员的你,只需要记住执行的通用操作就行了。通过多态性的应用,几个名字减少为一个。尽管这个例子相当简单,但如果你将这个概念扩展一下,你就会理解重载能够帮助你解决更复杂的问题。

出自: http://java.ccidnet.com/art/3555/20060405/498571_1.html

7.5 递 归
Java支持递归(recursion)。递归就是依照自身定义事物的过程。在Java编程中,递归是允许方法调用自身调用的属性。调用自身的方法称为是递归的(recursive)。
递归的典型例子是数字的阶乘。数字N的阶乘是1到N之间所有整数的乘积。例如3的阶乘就是1× 2×3,或者是6。下面的程序使用递归来计算数字的阶乘。
// A simple example of recursion.
class Factorial {
// this is a recursive function
int fact(int n) {
int result;
if(n==1) return 1;
result = fact(n-1) * n;
return result;
}
}
class Recursion {
public static void main(String args[]) {
Factorial f = new Factorial();
System.out.println("Factorial of 3 is " + f.fact(3));
System.out.println("Factorial of 4 is " + f.fact(4));
System.out.println("Factorial of 5 is " + f.fact(5));
}
}
该程序产生的输出如下所示:
Factorial of 3 is 6
Factorial of 4 is 24
Factorial of 5 is 120
如果你对递归的方法比较陌生,那么fact( )的操作可能看起来似乎有点糊涂。它是这样工作的:当fact( )带着参数1被调用时,该方法返回1;否则它返回fact( n-1 )与n的乘积。为
了对这个表达式求值,fact()带着参数n-1被调用。重复这个过程直到 n 等于 1,且对该方法的调用开始返回。
为了更好地理解fact( )方法是如何工作的,让我们通过一个短例子来说明。例如当计算3 的阶乘时,对fact()的第一次调用引起参数2的第二次调用。这个调用将引起fact以参数1的第三次调用,这个调用返回1,这个值接着与2(第二次调用时n的值)相乘。然后该结果(现为2)返回到fact()的最初的调用,并将该结果与3(n的初始值)相乘。这时得到答案,6。如果你在fact()中插入println()语句,显示每次调用的阶数以及中间结果,你会觉得很有意思。当一个方法调用它自身的时候,堆栈就会给新的局部变量和自变量分配内存,方法代码就带着这些新的变量从头执行。递归调用并不产生方法新的拷贝。只有参数是新的。每当递归调用返回时,旧的局部变量和自变量就从堆栈中清除,运行从方法中的调用点重新开始。递归方法可以说是像“望远镜”一样,可以自由伸缩。许多子程序的递归版本执行时会比它们的迭代版本要慢一点,因为它们增加了额外的方法调用的消耗。对一个方法太多的递归调用会引起堆栈崩溃。因为自变量和局部变量的存储都在堆栈中,每次调用都创建这些变量新的拷贝,堆栈有可能被耗尽。如果发生这种情况,Java的运行时系统就会产生异常。但是,除非递归子程序疯狂运行,否则你大概不会担心这种情况。递归的主要优点在于:某些类型的算法采用递归比采用迭代算法要更加清晰和简单。例如快速排序算法按照迭代方法是很难实现的。还有其他一些问题,特别是人工智能问题,就依赖于递归提供解决方案。最后,有些人认为递归要比迭代简单。当编写递归方法时,你必须使用if条件语句在递归调用不执行时来强制方法返回。如果你不这么做,一旦你调用方法,它将永远不会返回。这类错误在使用递归时是很常见的。

出自: http://java.ccidnet.com/art/3555/20060405/498571_4.html

7.7 理解static
有时你希望定义一个类成员,使它的使用完全独立于该类的任何对象。通常情况下,类成员必须通过它的类的对象访问,但是可以创建这样一个成员,它能够被它自己使用,而不必引用特定的实例。在成员的声明前面加上关键字static(静态的)就能创建这样的成员。
如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问,而不必引用任何对象。你可以将方法和变量都声明为static。static成员的最常见的例子是main( )。因为
在程序开始执行时必须调用main(),所以它被声明为static。
声明为static的变量实质上就是全局变量。当声明一个对象时,并不产生static变量的拷贝,而是该类所有的实例变量共用同一个static变量。
声明为static的方法有以下几条限制:
· 它们仅能调用其他的static方法。
· 它们只能访问static数据。
· 它们不能以任何方式引用this或super(关键字super与继承有关,在下一章中描述)。
如果你需要通过计算来初始化你的static变量,你可以声明一个static块,Static块仅在该类被加载时执行一次。下面的例子显示的类有一个static方法,一些static变量,以及一个static初始化块:
// Demonstrate static variables,methods,and blocks.
class UseStatic {
static int a = 3;
static int b;
static void meth(int x) {
System.out.println("x = " + x);
System.out.println("a = " + a);
System.out.println("b = " + b);
}
static {
System.out.println("Static block initialized.");
b = a * 4;
}
public static void main(String args[]) {
meth(42);
}
}
一旦UseStatic类被装载,所有的static语句被运行。首先,a被设置为3,接着static块执行(打印一条消息),最后,b被初始化为a*4或12。然后调用main(),main()调用meth(),把值42传递给x。3个println ( )语句引用两个static变量a和b,以及局部变量x 。注意:在一个static方法中引用任何实例变量都是非法的。下面是该程序的输出:
Static block initialized.
x = 42
a = 3
b = 12
在定义它们的类的外面,static方法和变量能独立于任何对象而被使用。这样,你只要在类的名字后面加点号运算符即可。例如,如果你希望从类外面调用一个static方法,你可
以使用下面通用的格式:classname.method( )
这里,classname 是类的名字,在该类中定义static方法。可以看到,这种格式与通过对象引用变量调用非static方法的格式类似。一个static变量可以以同样的格式来访问——类名加点号运算符。这就是Java如何实现全局功能和全局变量的一个控制版本。下面是一个例子。在main()中,static方法callme()和static变量b在它们的类之外被访问。
class StaticDemo {
static int a = 42;
static int b = 99;
static void callme() {
System.out.println("a = " + a);
}
}
class StaticByName {
public static void main(String args[]) {
StaticDemo.callme();
System.out.println("b = " + StaticDemo.b);
}
}
下面是该程序的输出:
a = 42
b = 99

出自: http://java.ccidnet.com/art/3555/20060405/498571_6.html

7.10 介绍嵌套类和内部类
在另一个类中定义的类就是嵌套类(nested classes)。嵌套类的范围由装入它的类的范围限制。这样,如果类B被定义在类A之内,那么B为A所知,然而不被A的外面所知。嵌套
类可以访问嵌套它的类的成员,包括private成员。但是,包围类不能访问嵌套类的成员。
嵌套类一般有2种类型:前面加static标识符的和不加static标识符的。
一个static的嵌套类有static修饰符。因为它是static,所以只能通过对象来访问它包围类的成员。也就是说,它不能直接引用它包围类的成员。因为有这个限制,所以static嵌套类很少使用。嵌套类最重要的类型是内部类(inner class)。内部类是非static的嵌套类。它可以访问它的外部类的所有变量和方法,它可以直接引用它们,就像外部类中的其他非static成员的功能一样。这样,一个内部类完全在它的包围类的范围之内。
下面的程序示例了如何定义和使用一个内部类。名为Outer的类有一个名为outer_x的示例变量,一个名为test()的实例方法,并且定义了一个名为Inner的内部类。
// Demonstrate an inner class.
class Outer {
int outer_x = 100;
void test() {
Inner inner = new Inner();
inner.display();
}
// this is an inner class
class Inner {
void display() {
System.out.println("display: outer_x = " + outer_x);
}
}
}
class InnerClassDemo {
public static void main(String args[]) {
Outer outer = new Outer();
outer.test();
}
}
该程序的输出如下所示:
display: outer_x = 100
在本程序中,内部类Inner定义在Outer类的范围之内。因此,在Inner类之内的任何代码可以直接访问变量outer_x。实例方法display()定义在Inner的内部,该方法以标准的输出流显示 outer_x。InnerClassDemo的main( )方法创建类Outer的一个实例并调用它的test( )方法。
创建类Inner和display()方法的一个实例的方法被调用。认识到Inner类只有在类Outer的范围内才是可知的是很重要的。如果在类Outer之外的任何代码试图实例化Inner类,Java编译器会产生一条错误消息。总体来说,一个嵌套类和其他任何另外的编程元素没有什么不同:它仅仅在它的包围范围内是可知的。
我们解释过,一个内部类可以访问它的包围类的成员,但是反过来就不成立了。内部类的成员只有在内部类的范围之内是可知的,而且不能被外部类使用。例如:
// This program will not compile.
class Outer {
int outer_x = 100;
void test() {
Inner inner = new Inner();
inner.display();
}
// this is an inner class
class Inner {
int y = 10; // y is local to Inner
void display() {
System.out.println("display: outer_x = " + outer_x);
}
}
void showy() {
System.out.println(y); // error,y not known here!
}
}
class InnerClassDemo {
public static void main(String args[]) {
Outer outer = new Outer();
outer.test();
}
}
这里,y是作为Inner的一个实例变量来声明的。这样对于该类的外部它就是不可知的,因此不能被showy()使用。尽管我们强调嵌套类在它的外部类的范围之内声明,但在几个程序块的范围之内定义内部类是可能的。例如,在由方法定义的块中,或甚至在for循环体内部,你也可以定义嵌套类,如下面的程序所示:
// Define an inner class within a for loop.
class Outer {
int outer_x = 100;
void test() {
for(int i=0; i<10; i++) {
class Inner {
void display() {
System.out.println("display: outer_x = " + outer_x);
}
}
Inner inner = new Inner();
inner.display();
}
}
}
class InnerClassDemo {
public static void main(String args[]) {
Outer outer = new Outer();
outer.test();
}
}
该程序的这个版本的输出如下所示。
display: outer_x = 100
display: outer_x = 100
display: outer_x = 100
130 第1 部分 Java 语言
display: outer_x = 100
display: outer_x = 100
display: outer_x = 100
display: outer_x = 100
display: outer_x = 100
display: outer_x = 100
display: outer_x = 100
尽管嵌套类在日常的大多数编程中不使用,但当处理applet(小应用程序)时是特别有帮助的。在第20章中我们将继续嵌套类的话题。在那里你将看到对于某些类型的事件内部类如何被用来简化代码。你也将了解匿名内部类(anonymous inner classes),它是一个没有名字的内部类。
最后一点:嵌套类在Java的最初的1.0版本中是不允许的。直到Java 1.1中才添加了嵌套类。

出自 : http://java.ccidnet.com/art/3555/20060405/498571_7.html

超类(super class ) 与 子类 (subclass)

// This program uses inheritance to extend Box.
class Box {
double width;
double height;
double depth;
// construct clone of an object
Box(Box ob) { // pass object to constructor
width = ob.width;
height = ob.height;
depth = ob.depth;
}
// constructor used when all dimensions specified
Box(double w, double h, double d) {
width = w;
height = h;
depth = d;
}
// constructor used when no dimensions specified
Box() {
width = -1; // use -1 to indicate
height = -1; // an uninitialized
depth = -1; // box
}
// constructor used when cube is created
Box(double len) {
width = height = depth = len;
}
// compute and return volume
double volume() {
return width * height * depth;
}
}
// Here, Box is extended to include weight.
class BoxWeight extends Box {
double weight; // weight of box
// constructor for BoxWeight
BoxWeight(double w, double h, double d, double m) {
width = w;
height = h;
depth = d;
weight = m;
}
}
class DemoBoxWeight {
public static void main(String args[]) {
BoxWeight mybox1 = new BoxWeight(10, 20, 15, 34.3);
BoxWeight mybox2 = new BoxWeight(2, 3, 4, 0.076);
double vol;
vol = mybox1.volume();
System.out.println("Volume of mybox1 is " + vol);
System.out.println("Weight of mybox1 is " + mybox1.weight);
System.out.println();
vol = mybox2.volume();
System.out.println("Volume of mybox2 is " + vol);
System.out.println("Weight of mybox2 is " + mybox2.weight);
}
}
该程序的输出显示如下:
Volume of mybox1 is 3000.0
Weight of mybox1 is 34.3
Volume of mybox2 is 24.0
Weight of mybox2 is 0.076
BoxWeight继承了Box的所有特征并为自己增添了一个weight成员。没有必要让BoxWeight重新创建Box中的所有特征。为满足需要我们只要扩展Box就可以了。继承的一个主要优势在于一旦你已经创建了一个超类,而该超类定义了适用于一组对象的属性,它可用来创建任何数量的说明更多细节的子类。每一个子类能够正好制作它自己的分类。例如,下面的类继承了Box并增加了一个颜色属性:
// Here, Box is extended to include color.
class ColorBox extends Box {
int color; // color of box
ColorBox(double w, double h, double d, int c) {
width = w;
height = h;
depth = d;
color = c;
}
}
记住,一旦你已经创建了一个定义了对象一般属性的超类,该超类可以被继承以生成特殊用途的类。每一个子类只增添它自己独特的属性。这是继承的本质。
8.1.3 超类变量可以引用子类对象
你将发现继承的这个方面在很多条件下是很有用的。例如,考虑下面的程序:
class RefDemo {
public static void main(String args[]) {
BoxWeight weightbox = new BoxWeight(3, 5, 7, 8.37);
Box plainbox = new Box();
double vol;
vol = weightbox.volume();
System.out.println("Volume of weightbox is " + vol);
System.out.println("Weight of weightbox is " +
weightbox.weight);
System.out.println();
// assign BoxWeight reference to Box reference
plainbox = weightbox;
vol = plainbox.volume(); // OK, volume() defined in Box
System.out.println("Volume of plainbox is " + vol);
/* The following statement is invalid because plainbox
does not define a weight member. */
// System.out.println("Weight of plainbox is " + plainbox.weight);
}
}
这里,weightbox是BoxWeight对象的一个引用,plainbox是Box对象的一个引用。既然BoxWeight是Box的一个子类,允许用一个weightbox对象的引用给plainbox赋值。理解是引用变量的类型——而不是引用对象的类型——决定了什么成员可以被访问。也就是说,当一个子类对象的引用被赋给一个超类引用变量时,你只能访问超类定义的对象的那一部分。这是为什么plainbox不能访问weight的原因,甚至是它引用了一个BoxWeight对象也不行。仔细想一想,这是有道理的,因为超类不知道子类增加的属性。这就是本程序中的最后一行被注释掉的原因。Box的引用访问weight域是不可能的,因为它没有定义。尽管前面部分看起来有一点深奥,它是很重要的实际应用——本章后面将讨论的两种应用之一。

出自 : http://java.ccidnet.com/art/3555/20060412/503427_2.html

8.4 何时调用构造函数
类层次结构创建以后,组成层次结构的类的构造函数以怎样的顺序被调用?举个例子来说,给定一个名为B的子类和超类A,是A的构造函数在B的构造函数之前调用,还是情况相反?回答是在类层次结构中,构造函数以派生的次序调用,从超类到子类。而且,尽管super( )必须是子类构造函数的第一个执行语句,无论你用到了super( )没有,这个次序不变。如果super( )没有被用到,每个超类的默认的或无参数的构造函数将执行。下面的例子阐述了何时执行构造函数:
// Demonstrate when constructors are called.
// Create a super class.
class A {
A() {
System.out.println("Inside A's constructor.");
}
}
// Create a subclass by extending class A.
class B extends A {
B() {
System.out.println("Inside B's constructor.");
}
}
// Create another subclass by extending B.
class C extends B {
C() {
System.out.println("Inside C's constructor.");
}
}
class CallingCons {
public static void main(String args[]) {
C c = new C();
}
}
该程序输出如下:
Inside A’s constructor
Inside B’s constructor
Inside C’s constructor
如你所见,构造函数以派生的顺序被调用。仔细考虑,构造函数以派生的顺序执行是很有意义的。因为超类不知道任何子类的信息,任何它需要完成的初始化是与子类的初始化分离的,而且它可能是完成子类初始化的先决条件。因此,它必须最先执行。

出自 : http://java.ccidnet.com/art/3555/20060412/503427_5.html

final的用途

final在JAVA中有三个用途:  

 1.定义一个已知变量名的常量. final写在数据类型前.例 final int PI = 3.14  此常量只能在声明时赋值 且在程序运行过程中不能改变

2. 阻止方法的重载 . final写在方法的返回类型前 例 public final void text(){}   方法重载是JAVA的一个重要的特点,但有时你不希望该方法再被重载时,可以用final阻止

3.阻止类再被继承  final写在类名前.   例 final class a{}  继承为面向对象语言的一大特色,当你不想该类再被其它类继承时,可用final阻止

 

异常 :

异常 说明
ArrayStoreException 数组元素赋值类型不兼容
ClassCastException 非法强制转换类型
IllegalArgumentException 调用方法的参数非法
IllegalMonitorStateException 非法监控操作,如等待一个未锁定线程
IllegalStateException 环境或应用状态不正确
IllegalThreadStateException 请求操作与当前线程状态不兼容
IndexOutOfBoundsException 某些类型索引越界
NullPointerException 非法使用空引用
NumberFormatException 字符串到数字格式非法转换
SecurityException 试图违反安全性
StringIndexOutOfBounds 试图在字符串边界之外索引
UnsupportedOperationException 遇到不支持的操作
表10-2 java.lang 中定义的检查异常
异常 意义
ClassNotFoundException 找不到类
CloneNotSupportedException 试图克隆一个不能实现Cloneable接口的对象
IllegalAccessException 对一个类的访问被拒绝
InstantiationException 试图创建一个抽象类或者抽象接口的对象
InterruptedException 一个线程被另一个线程中断
NoSuchFieldException 请求的字段不存在
NoSuchMethodException 请求的方法不存在

出自: http://java.ccidnet.com/art/3555/20060420/515415_5.html

流类 含义
BufferedInputStream 缓冲输入流
BufferedOutputStream 缓冲输出流
ByteArrayInputStream 从字节数组读取的输入流
ByteArrayOutputStream 向字节数组写入的输出流
DataInputStream 包含读取Java标准数据类型方法的输入流
DataOutputStream 包含编写Java 标准数据类型方法的输出流
FileInputStream 读取文件的输入流
FileOutputStream 写文件的输出流
FilterInputStream 实现 InputStream
FilterOutputStream 实现 OutputStream
InputStream 描述流输入的抽象类
OutputStream 描述流输出的抽象类
PipedInputStream 输入管道
PipedOutputStream 输出管道
PrintStream 包含print( ) 和 println( )的输出流
PushbackInputStream 支持向输入流返回一个字节的单字节的“unget”的输入流
RandomAccessFile 支持随机文件输入/输出
SequenceInputStream 两个或两个以上顺序读取的输入流组成的输入流
抽象类InputStream 和 OutputStream定义了实现其他流类的关键方法。最重要的两种方法是read()和write(),它们分别对数据的字节进行读写。两种方法都在InputStream 和OutputStream中被定义为抽象方法。它们被派生的流类重载。
字符流类
字符流类由两个类层次结构定义。顶层有两个抽象类:Reader和Writer。这些抽象类处理统一编码的字符流。Java中这些类含有多个具体的子类。字符流类如表12-2所示。
表12-2 字符流的输入/输出类
流类 含义
BufferedReader 缓冲输入字符流
BufferedWriter 缓冲输出字符流
CharArrayReader 从字符数组读取数据的输入流
CharArrayWriter 向字符数组写数据的输出流
FileReader 读取文件的输入流
FileWriter 写文件的输出流
FilterReader 过滤读
FilterWriter 过滤写
InputStreamReader 把字节转换成字符的输入流
LineNumberReader 计算行数的输入流
OutputStreamWriter 把字符转换成字节的输出流
PipedReader 输入管道
PipedWriter 输出管道
PrintWriter 包含print( )和println( )的输出流
PushbackReader 允许字符返回到输入流的输入流
Reader 描述字符流输入的抽象类
StringReader 读取字符串的输入流
StringWriter 写字符串的输出流
Writer 描述字符流输出的抽象类
抽象类Reader和Writer定义了几个实现其他流类的关键方法。其中两个最重要的是read()和write(),它们分别进行字符数据的读和写。这些方法被派生流类重载。

出自: http://java.ccidnet.com/art/3555/20060426/529073_1.html


原创粉丝点击