内部类的使用:
内部类的使用的优缺点:
优点:减少了在类文件编译后的产生的字节码文件的大小
缺点:使程序结构不清晰
使用内部类的注意事项:
内部类的使用一般都与所在的外部类有一定的关联,它是在一个类的内部嵌套定义的类,它可以是其它类的成员,也可以在一个语句块的内部定义,还可以在表达式内部匿名定义(匿名内部类)。
内部类有如下的特性:
.一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称,名字不能与包含它的数百名相同
. 可以使用包含它的类的表态和实例成员变量,也可以使用它所在方法的局部变量
.可以定义为abstract
.若被声明为static,就变成了顶层类,不能再使用局部变量
.若想在inner class 中声明任何static成员,则该inner class必须声明为static.
.匿名类是一种特殊的内部类,它是在一个表达式的内部包含一个完整的类的定义。匿名内部类不需要任何的修饰词。
.内部类可以使用任何听修饰符,但是如果声明为static类,则等同于一个标准类。
.如果非表态内部类,就拥有对外部类的所有成员的完全访问权限,包括实例字段和方法。为实现这一行为,非表态内部类存着对外部类的实例的一个隐匿的引用。
.所以对一个非表态内部类进行实例化需要采用不同语法的new 语句,这种开工的new 语句要求外部类的一个实例,使内部类能在那个实例的上下文中创建。
.非表态内部类具有一些限制。尤其是,它们不能声明表态初始化列表和表态成员,除非是在常量字段中。此外方法内部声明的内部类不能访问方法的局部变量和参数,除非它们被初始化成final.
.表态内部类当中可以有表态数据,表态方法或者是又一个表态内部类。而非表态内部类当中不能有静态数据。这是它们的区别。
.局部内部类:Java内部类也可以是局部的,它可以定义在一个方法甚至一个代码块之内。
有一点需要注意的是,匿名内部类由于没有名字,所以它没有构造函数(但是如果这个匿名内部类继承了一个只含有带参数构造函数的父类,创建它的时候必须带上这些参数,并在实现的过程中使用super关键字调用相应的内容)。如果你想要初始化它的成员变量,有下面几种方法:
如果是在一个方法的匿名内部类,可以利用这个方法传进你想要的参数,不过记住,这些参数必须被声明为final。
将匿名内部类改造成有名字的局部内部类,这样它就可以拥有构造函数了。
在这个匿名内部类中使用初始化代码块。
为什么需要内部类?
java内部类有什么好处?为什么需要内部类?
首先举一个简单的例子,如果你想实现一个接口,但是这个接口中的一个方法和你构想的这个类中的一个方法的名称,参数相同,你应该怎么办?这时候,你可以建一个内部类实现这个接口。由于内部类对外部类的所有内容都是可访问的,所以这样做可以完成所有你直接实现这个接口的功能。
不过你可能要质疑,更改一下方法的不就行了吗?
的确,以此作为设计内部类的理由,实在没有说服力。
真正的原因是这样的,java中的内部类和接口加在一起,可以的解决常被C++程序员抱怨java中存在的一个问题——没有多继承。实际上,C++的多继承设计起来很复杂,而java通过内部类加上接口,可以很好的实现多继承的效果。
下面是使用内部类的几个小例子:
JAVA的内部类的构造方法是不会自动调用,必须在外部类当中的某个方法当中或构造函数当中显示调用才能够正确使用。
Class Outer{
public outer(){
System.out.println("....");
}
Class Inner{
public Innter(){
System.out.println("inner");
}
}
public static void Main(String[] args){
Outer a = new Outer();
}
}
这种使用方法不会关系到内部类的输出。因为它并没有显示调用内部类。
所以我们应该进行这样的修改:
在Outer构造函数中加入 Innter b = new Innter();
就可以直接调用它的输出或方法体了。
不过我们经常使用的还是匿名内部类:
class Outer{
Outer(){
(new Inner(){
public void print(){
System.out.println("Inner");
}
}
).print();
System.out.println("Outer");
}
}
下面是JAVA的一个源码使用了匿名内部类:
/**
* "Tokenizes" the entire stream as a single token.
*/
public class KeywordAnalyzer extends Analyzer {
public TokenStream tokenStream(String fieldName,
final Reader reader) {
return new TokenStream() {
private boolean done;
private final char[] buffer = new char[1024];
public Token next() throws IOException {
if (!done) {
done = true;
StringBuffer buffer = new StringBuffer();
int length = 0;
while (true) {
length = reader.read(this.buffer);
if (length == -1) break;
buffer.append(this.buffer, 0, length);
}
String text = buffer.toString();
return new Token(text, 0, text.length());
}
return null;
}
};
}
}
posted on 2006-08-01 08:53
水煮三国 阅读(7250)
评论(3) 编辑 收藏 所属分类:
J2SE