`

匿名类、内部类、匿名内部类

    博客分类:
  • Java
阅读更多

 

前端时间在写.net项目中,一直错将.cs里的两个class当作内部类,原来是一个文件里的两个类而已,这让我想起了Java中的内部类,比较内部类,那么还有两个类,那就是匿名类和匿名内部类。今天我想就Java中的这三种类进行个比较。

我们知道在Java语言规范中可以做很多事,例如一个类或一个接口中可以声明一个类或接口,在一个方法中可以声明一个类,类与接口声明可以嵌套任意深度等。

 

匿名类:

      1new <类或接口><类的主体>,匿名类的声明是在编译时进行的,实例化是在运行时进行的,所以在for循环中一个new语句会创建相同匿名类的几个实例,而不是创建几个不同匿名类的一个实例。

      2、如果要执行的对象需要一个对象,但却不值得创建全新的对象(可能是因为该对象只在一个方法内部使用),在这个时候使用匿名类就会非常合适,所以说,匿名类一般会在swing程序中快速创建事件处理程序。

	firstButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				getTxtValue().setText("第一个按钮触发的事件!");
			}
		});	

       3、从技术上说,匿名类可以被看作非静态的内部类,所以他们具有方法内部声明的非静态内部类相同的权限和限制。

 

 

内部类:

内部类顾名思义就是在一个类的内部还有一个类

package com.iflytek.innerclass;

/**
 * @author xudongwang 2012-1-11
 * 
 *         Email:xdwangiflytek@gmail.com
 */
public class InnerClassDemo {
	public static void main(String[] args) {
		new Outer().fun();
	}
}

class Outer {

	private String name = "Hello 内部类";

	class Inner {
		public void print() {
			System.out.println("name = " + name);

		}
	};

	public void fun() {
		new Inner().print();
	}
}

 

 内部类生成的.class文件名为:Outer$Inner.class,从上面的结构发现内部类的的缺点是“结构非常的混乱”。

package com.iflytek.innerclass;

/**
 * @author xudongwang 2012-1-11
 * 
 *         Email:xdwangiflytek@gmail.com
 */
public class InnerClassDemo02 {
	public static void main(String[] args) {
		new Outer02().fun();
	}
}

class Outer02 {

	private String name = "Hello 内部类";

	public void fun() {
		new Inner02(this).print();
	}

	public String getName() {

		return this.name;
	}
};

class Inner02 {
	private Outer02 out;

	public Inner02(Outer02 out) {
		this.out = out;
	}

	public void print() {
		System.out.println("name = " + this.out.getName());

	}
};

 从上可以看出内部类的优点是“可以方便的访问外部类中的私有成员”;

如果要在外部直接使用内部类的实例化对象:

      外部类.内部类 内部类对象 = 外部类实例.new 内部类实例();

package com.iflytek.innerclass;

/**
 * @author xudongwang  2012-1-11
 *
 *  Email:xdwangiflytek@gmail.com
 */
public class InnerClassDemo03 {
	public static void main(String[] args) {
		Outer03 out = new Outer03();//外部类实例
		Outer03.Inner inner = out.new Inner();//实例化内部类对象
		inner.print();
	}
}
class Outer03{
	private String name = "Hello 内部类";
	class Inner {
		public void print() {
			System.out.println("name = " + name);
		}
	}
}

 

 一个内部类如果使用static关键字声明的话,则此内部类就将成为外部类,可以直接通过外部类.内部类的形式访问

package com.iflytek.innerclass;

/**
 * @author xudongwang 2012-1-11
 * 
 *         Email:xdwangiflytek@gmail.com
 */
public class InnerClassDemo04 {
	public static void main(String[] args) {
		Outer04.Inner inner = new Outer04.Inner();// 实例化内部类对象
		inner.print();
	}
}

class Outer04 {
	private static String name = "Hello 内部类";

	static class Inner {
		public void print() {
			System.out.println("name = " + name);
		}
	}
}

 

 内部类可以在任意的地方使用,例如方法中声明

package com.iflytek.innerclass;

/**
 * @author xudongwang 2012-1-11
 * 
 *         Email:xdwangiflytek@gmail.com
 */
public class InnerClassDemo05 {
	public static void main(String[] args) {
		new Outer05().fun();
	}
}

class Outer05 {
	private static String name = "Hello 内部类";

	public void fun() {
		class Inner {
			public void print() {
				System.out.println("name = " + name);
			}
		}
		new Inner().print();
	}
}

 

 在方法中定义的内部类,可以直接访问外部类中的各个成员,但是如果要访问方法中的参数,则需要在参数上加上final关键字声明;

package com.iflytek.innerclass;

/**
 * @author xudongwang 2012-1-11
 * 
 *         Email:xdwangiflytek@gmail.com
 */
public class InnerClassDemo06 {
	public static void main(String[] args) {
		new Outer06().fun(20);
	}
}

class Outer06 {
	private static String name = "Hello 内部类";

	public void fun(final int temp) {
		class Inner {
			public void print() {
				System.out.println("temp = " + temp);
				System.out.println("name = " + name);
			}
		}
		new Inner().print();
	}
}

 匿名类与内部的联系与区别:

按所在位置可以分为两大类:

      1、在类的方法中

                     特点:

                              a、可以访问宿主类的所有元素 ;

                              b、保存宿主类对象的引用,创建对象时必须有宿主类对象;

                              c、 不能有静态数据;

继续划分:

                             A、本地内部类;

                             B、匿名内部类

 两者的区别在于本地内部类有构造方法,而匿名内部类只能实例初始化;

      2、在类或接口作用域中;

                     继续划分:

                            A、普通内部类

                            B、静态内部类

 

 

匿名内部类:

匿名内部类是在抽象类和接口的基础之上发展起来的。

package com.iflytek.innerclass;

/**
 * @author xudongwang 2012-1-11
 * 
 *         Email:xdwangiflytek@gmail.com
 */
public class NoNameClass01 {
	public static void main(String[] args) {
		new X().fun2();
	}
}

interface A {
	public void fun();
}

class B implements A {
	public void fun() {

		System.out.println("Hello 准备匿名内部类");
	}
}

class X {
	public void fun1(A a) {
		a.fun();
	}

	public void fun2() {
		this.fun1(new B());
	}
}

 通过上面的Demo,如果现在假设B类只使用一次,那么还有必要将其定义成一个单独的类么?

 呵呵,此时就可以使用匿名内部类:

package com.iflytek.innerclass;

/**
 * @author xudongwang 2012-1-11
 * 
 *         Email:xdwangiflytek@gmail.com
 */
public class NoNameClass02 {

	public static void main(String[] args) {
		new XX().fun2();
	}
}

interface AA {
	public void fun();
}

class XX {
	public void fun1(AA a) {
		a.fun();
	}
	public void fun2() {
		this.fun1(new AA() {
			public void fun() {
				System.out.println("Hello 准备匿名内部类");
			}
		});
	}
}

 其实在真正的项目开发中匿名内部类使用的非常之少,一般在Java的图形界面和现在的Android中使用的比较多点。

 

 最后给一个内部类实现的简单链表:

package com.iflytek.innerclass;

/**
 * @author xudongwang 2012-1-11
 * 
 *         Email:xdwangiflytek@gmail.com
 */
public class LinkDemo {
	public static void main(String args[]) {
		Link link = new Link();
		link.add("A");
		link.add("B");
		link.add("C");
		link.add("D");
		link.add("E");
		link.print();
	}
};

class Link {
	class Node {
		private String name;
		private Node next; // 单向链表,每个节点指向下一个节点

		public Node(String name) {
			this.name = name; // 通过构造方法为name属性赋值
		}

		public void addNode(Node newNode) { // 增加节点
			if (this.next == null) {
				this.next = newNode; // 保存节点
			} else {
				this.next.addNode(newNode); // 继续向下查找
			}
		}

		public void printNode() { // 输出节点
			System.out.println(this.name);
			if (this.next != null) { // 此节点之后还存在其他的节点
				this.next.printNode();
			}
		}
	};

	private Node root; // 链表的头

	public void add(String name) { // 增加节点
		Node newNode = new Node(name); // 定义一个新的节点
		/*
		 * 如果是第一个节点,则肯定是根节点, 如果是第二个节点,则肯定放在根节点next中 如果是第三个节点,则肯定放在第二个节点的next中
		 */
		if (this.root == null) {
			this.root = newNode; // 将第一个节点设置成根节点
		} else {
			// 肯定要放在最后一个节点之后
			// 通过节点.next来不断的判断
			this.root.addNode(newNode);
		}
	}

	public void print() {
		if (this.root != null) { // 如果根节点为空了,则没有任何内容
			this.root.printNode();
		}
	}
};
 

 

 

0
0
分享到:
评论
1 楼 hanmiao 2012-11-09  
这個好,尤其喜欢最后那段用内部类实现的单链表,如果再加個反转的方法声明就更好了。

相关推荐

    java 内部类使用(内部匿名类)

    内部类分为几种类型,包括成员内部类、局部内部类、匿名内部类以及方法参数内部类。 1. **成员内部类**:成员内部类就像是外部类的一个普通成员,可以是静态或非静态的。非静态内部类拥有对外部类的引用,可以直接...

    java中的匿名内部类总结

    Java 中的匿名内部类总结 Java 中的匿名内部类是一种特殊的内部类,它没有名字,因此也称为匿名类。匿名内部类是一种简洁的编程方式,能够简化代码编写,但它也有一些限制和特点。 匿名内部类的定义 匿名内部类是...

    匿名类/内部类/本地类 解读

    内部类分为成员内部类、局部内部类和匿名内部类。成员内部类就像是外部类的一个成员变量,可以在外部类的任何地方使用;局部内部类则定义在方法或代码块内,其作用域仅限于该方法或代码块。例如: ```java public ...

    java 匿名内部类的使用规范

    Java匿名内部类是Java语言中一个独特且强大的特性,它允许我们在不需要定义一个单独的类的情况下创建类的实例。这在处理回调、事件监听、单例模式以及其他需要短时间内定义一个简单类的情况时非常有用。本篇文章将...

    Java4Android 35_内部类和匿名内部类

    在Java编程语言中,内部类和匿名内部类是两种特殊类型的类,它们为代码的组织和功能实现提供了独特的灵活性。本教程"Java4Android 35_内部类和匿名内部类"深入探讨了这两个概念,旨在帮助开发者更好地理解和运用它们...

    内部类知识总结3--匿名内部类

    内部类可以是静态的,也可以是非静态的,而匿名内部类则是一种没有名字的内部类,通常用于快速实现简单的回调或者接口实现。这篇总结将深入探讨匿名内部类的相关知识点。 1. **匿名内部类的概念** 匿名内部类是...

    Java 匿名内部类

    Java匿名内部类是Java语言中一个独特且强大的特性,它允许我们在不定义单独类的情况下创建对象。这种类没有名字,通常用作一次性实现某个接口或继承某个类的需求。在Java编程中,匿名内部类主要用于事件处理、回调...

    Android开发匿名内部类

    在Java编程语言中,匿名内部类是一种特殊的类,它没有名字,通常用于简化代码和实现特定功能,如事件处理或接口快速实现。在Android开发中,匿名内部类的应用尤其广泛,因为Android框架中的许多组件(如按钮、文本...

    匿名内部类代码

    匿名内部类是Java编程语言中一个独特且强大的特性,它允许我们在需要的地方直接定义一个类的实例,而无需声明一个独立的类。这种类没有名字,通常用于实现接口或者继承抽象类,尤其在事件处理、回调函数以及创建一次...

    内部类 匿名内部类 内部接口 对比说明

    本文将详细探讨内部类、匿名内部类以及内部接口的对比和使用。 首先,让我们了解一下内部类的基本概念。内部类定义在其他类的内部,编译后会生成两个独立的类文件。内部类能够自由地访问外部类的所有成员,包括私有...

    Android 匿名内部类作为事件监听类

    在Android开发中,匿名内部类是一种常见的编程技巧,它允许我们快速实现事件监听功能,而无需定义单独的类。本文将深入探讨如何使用匿名内部类作为事件监听类,以及其在Android开发中的应用。 首先,我们需要理解...

    发两个匿名内部类使用的例子

    在Java编程语言中,匿名内部类是一种特殊的类,它没有名字,通常用于简化代码和实现特定功能。在标题“发两个匿名内部类使用的例子”中,我们将会探讨两种不同的场景,如何利用匿名内部类来解决问题。这篇博客文章的...

    匿名内部类核心重点知识讲解和经典例子讲解

    匿名内部类是Java编程语言中一个独特且强大的特性,它允许我们在定义类的同时不为它提供名字。这种类主要用于创建一次性使用的对象,特别是在需要实现某个接口或者继承某个类的场合,而无需创建独立的文件来定义这个...

    匿名内部类实现接口回调

    这个"匿名内部类实现接口回调"的示例旨在演示如何通过匿名内部类来简化回调函数的实现。下面我们将详细探讨接口回调的概念、匿名内部类的使用以及它们在实际编程中的应用。 首先,让我们理解什么是接口回调。接口回...

    16.java匿名内部类.zip

    16.java匿名内部类.zip16.java匿名内部类.zip16.java匿名内部类.zip16.java匿名内部类.zip16.java匿名内部类.zip16.java匿名内部类.zip16.java匿名内部类.zip16.java匿名内部类.zip16.java匿名内部类.zip16.java匿名...

    java 内部类 局部内部类 匿名类 实例代码

    本篇文章将深入探讨Java中的四种内部类:实例内部类、局部内部类、匿名类和静态内部类,并通过实例代码进行详细解析。 1. **实例内部类**:这是最常见的内部类形式,它在外部类的实例方法或成员位置定义。实例内部...

    Handler对象中使用匿名内部类或非静态内部类正确地释放消息避免内存泄漏或增加Native内存

    然而,不当使用Handler,尤其是结合匿名内部类或非静态内部类,可能导致内存泄漏和Native内存增加,这对应用性能和稳定性造成负面影响。 首先,我们要理解内存泄漏的概念。内存泄漏是指程序中已分配的内存没有被...

    使用内部和匿名类优化Java代码

    Java 1.1 引入了内部类和匿名类,这两种特性极大地增强了代码的灵活性和可读性。内部类是指定义在另一个类内部的类,它可以是静态的或非静态的,根据其是否需要访问外部类的实例成员来区分。静态内部类与普通类的...

    Java中的内部类和匿名类

    Java 中的内部类和匿名类 Java 中的内部类(Inner Class)可能很多人不太熟悉,实际上类似的概念在 C++ 里也有,那就是嵌套类(Nested Class)。内部类从表面上看,就是在类中又定义了一个类,而实际上并没有那么...

Global site tag (gtag.js) - Google Analytics