`
zero_lx
  • 浏览: 17267 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java中的内部类机制

 
阅读更多

可以将一个类的定义放在另一个类的定义内部,这就是内部类。内部类可以使用外部类的私有属性而不会破坏封装性,而且内部类可以访问外部类的所有方法与属性,但static的内部类只能访问外部类的静态属性与方法。内部类又可以分为成员内部类、静态内部类、局部内部类和匿名内部类。

 

首先说下成员内部类,类似于外部类的实例属性或函数,成员类有public/private/default权限修饰符。一个成员类实例必然所属一个外部类实例,成员类可访问外部类的任一个实例字段或实例函数。成员类内部访问其所属外部类实例采用"OuterClass.this .属性 "的形式,在内部类中访问实例变量:"this.属性"。 对于给定的一个外部类实例outerClass,可以直接创建其内部类实例,语法形式为"OuterClass.InnerClass innerClass=outerClass.new InnerClass()",成员类不能与外部类重名。不能在成员类中定义static字段、方法和类。因为一个成员类实例必然与一个外部类实例关联,而且静态属性是在加载类的时候创建,这个时候内部类还没有被创建成员类不能是接口,因为成员类必须能被某个外部类实例化,而接口不能实例化。成员类的显著特性就是成员类能访问它的外部类实例的任意字段与方法。

 

public class Parcel1 {

	private String str="hello";
	
	public class Contents{
		private int i=11;
		public int value(){
			return i;
		}
	}
	
	class Destination{
		private String label;
		Destination(String whereTo){
			label=whereTo;
		}
		String readLabel(){
			return Parcel1.this.str+","+label;
		}
		
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Parcel1 p=new Parcel1();
		Parcel1.Contents c=p.new Contents();
		System.out.println(c.value());
		Parcel1.Destination d=p.new Destination("world");
		System.out.println(d.readLabel());
		
	}

}

 

  注意在创非静态内部类对象时,一定要先创建相应的外部类对象。非静态内部类对象有着指向其外部类对象的引用,可以访问创建它的外部类对象的内容,甚至包括私有变量。非静态内部类不能声明本类的static成员,只有静态内部类才可以声明一个static成员。成员内部类可以直接访问外部类的非静态或静态成员、方法。

 

 

 

静态内部类:类声明中包含static关键字的内部类,在静态内部类中只能访问外部类的静态成员。在外部类的外部,要创建一个静态内部类对象不需要外部类对象:Outer.Inner in = new Outer.Inner();

public class Parcel11 {

	private static class ParcelContents implements Contents{
		private int i=11;
		public int value(){
			return i;
		}
	}
	
	protected static class ParcelDestination implements Destination{
		private String label;
		private ParcelDestination(String whereTo){
			label=whereTo;
		}
		public String readLabel(){
			return label;
		}
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Parcel11.ParcelContents c=new Parcel11.ParcelContents();
		System.out.println(c.value());
		
		Parcel11.ParcelDestination d=new Parcel11.ParcelDestination("hello");
		System.out.println(d.readLabel());
		
	}

}

 静态内部类没有指向外部类的引用,可以定义任何静态和非静态成员,在静态内部类中只能访问外部类的静态成员。

 

如果我们在用一个内部类的时候仅需要创建它的一个对象并传给外部类,就可以创建一个局部内部类并返回。局部内部类: 在外部类的方法中定义的内部类,与局部变量类似,在局部内部类前不可以加修饰符public和private,其作用域为定义它的代码块,局部内部类不仅可以访问外部类的实例变量,还可以访问局部变量,但要求局部变量必须为final的
  在外部类的外部不可创建局部内部类对象,只能在局部内部类所在的方法中创建。

 

public class Parcel5 {

	public Destination destination(String s){
		class PDestination implements Destination{
			private String label;
			private PDestination(String whereTo){
				label=whereTo;
			}
			public String readLabel(){
				return label;
			}
		}
		
		return new PDestination(s);
		
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Parcel5 p=new Parcel5();
		Destination d=p.destination("Tasmania");
		System.out.println(d.readLabel());
	}

}

 

 

 

匿名内部类:一种特殊的局部内部类,没有名字,也没有class、extends、implements关键字,无构造,用一种隐含的方式实现一个接口或继承一个类,并且只能创建一次实例。匿名内部类属于局部内部类,那么局部内部类的所有限制都对其生效。匿名内部类是唯一一种无构造方法的类,因为构造器的名字必须和类名相同,而匿名内部类没有类名。
实现方式:在某个语句中,new 父类/父接口名字(){ 类体中实现方法 }

 

public class Parcel7 {

	public Contents contents(){
		return new Contents(){

			private int i=11;
			public int value() {
				// TODO Auto-generated method stub
				return i;
			}
			
		};
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Parcel7 p=new Parcel7();
		Contents c=p.contents();
		System.out.println(c.value());
	}

}
 
public class Parcel9 {

	public Destination destination(final String dest){
		return new Destination(){

			private String label=dest;
			public String readLabel() {
				// TODO Auto-generated method stub
				return label;
			}
			
		};
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Parcel9 p=new Parcel9();
		Destination d=p.destination("Tasmania");
		System.out.println(d.readLabel());
	}

}
 
局部类或匿名内部类能且只能访问其所属代码段中的声明为final的局部变量。为什么只能访问声明为final的局部变量呢?我们知道,局部变量在其所属的代码段(譬如某个函数)执行完毕后就会被回收,而一个局部类的实例却可以在其类定义所属代码段执行完毕后依然存在,如果它可操控非final的局部变量,用户就可以通过该实例修改已不存在的局部变量,无意义。
分享到:
评论

相关推荐

    JAVA_内部类_反射机制

    JAVA_内部类_反射机制

    Junit单元测试内部机制解析

    Junit java单元测试内部机制解析

    Java同步机制浅谈

    Java 对多线程的支持与同步机制深受大家的喜爱,似乎看起来使用了synchronized 关键 字就可以轻松地解决多线程共享数据同步问题。到底如何?――还得对synchronized 关键字 的作用进行深入了解才可定论。 总的说来,...

    JAVA垃圾回收机制

    垃圾收集GC(Garbage Collection)是Java语言的核心技术之一,之前我们曾专门探讨过Java 7新增的垃圾回收器G1的新特性,但在JVM的内部运行机制上看,Java的垃圾回收原理与机制并未改变。垃圾收集的目的在于清除不再...

    JAVA_API1.6文档(中文)

    java.awt.datatransfer 提供在应用程序之间和在应用程序内部传输数据的接口和类。 java.awt.dnd Drag 和 Drop 是一种直接操作动作,在许多图形用户界面系统中都会遇到它,它提供了一种机制,能够在两个与 GUI 中...

    华为内部java考题

    华为内部的java考题, JAVA考试知识覆盖要点: (1)常用的集合类,如Set、Map、List,以及常用的查找、遍历、排序操作; (2)多线程同步机制; (3)文件读写; (4)XML解析、基本的正则表达式; (5)类的加载和...

    JAVA虚拟机的类装载机制的原理分析与应用研究.pdf

    详细描述java虚拟机内部加载类机制和原理

    java的反射机制及其实际应用

    反射允许我们在编写与执行时,使我们的程序代码能够接入装载到JVM中的类的内部信息,而不是源代码中选定的类协作的代码。这使反射成为构建灵活的应用的主要工具。但需注意的是:如果使用不当,反射的成本很高。

    JAVA中的反射机制(内含大量实例)

    JAVA中的反射机制(内含大量实例)Java中,反射是一种强大的工具。它使您能够创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代表链接。反射允许我们在编写与执行时,使我们的程序代码能够接入装载到...

    JAVA中的反射机制

    Java中,反射是一种强大的工具。...反射允许我们在编写与执行时,使我们的程序代码能够接入装载到JVM中的类的内部信息,而不是源代码中选定的类协作的代码。这使反射成为构建灵活的应用的主要工具。

    内部类与反射机制详解

    这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fields...

    Java 1.6 API 中文 New

    java.awt.datatransfer 提供在应用程序之间和在应用程序内部传输数据的接口和类。 java.awt.dnd Drag 和 Drop 是一种直接操作动作,在许多图形用户界面系统中都会遇到它,它提供了一种机制,能够在两个与 GUI 中显示...

    JAVA_API1.8中文文档(CHM版).rar

    java.awt.dnd Drag 和 Drop 是一种直接操作动作,在许多图形用户界面系统中都会遇到它,它提供了一种机制,能够在两个与 GUI 中显示元素逻辑相关的实体之间传输信息。 java.awt.event 提供处理由 AWT 组件所激发的...

    JavaAPI1.6中文chm文档 part1

    java.awt.datatransfer 提供在应用程序之间和在应用程序内部传输数据的接口和类。 java.awt.dnd Drag 和 Drop 是一种直接操作动作,在许多图形用户界面系统中都会遇到它,它提供了一种机制,能够在两个与 GUI 中...

    Java类加载原理解析

    Java类加载原理解析,深度解剖了java中的类的执行内部机制!

    Java开发技术大全(500个源代码).

    DumpMethods.java 使用反射机制来获取类中的方法 getClassName.java 利用反射机制获取类的名字 invokeConstructor.java 利用反射机制调用构造器 invokeMethod.java 利用反射机制调用成员方法 listConstructors....

    Java高级程序设计实战教程第三章-Java反射机制.pptx

    3.2.1 Java反射机制的概念 Java反射机制在Java运行状态中,对于任意一个类,我们都能够知道这个类的所有属性和方法;, 对于任意一个对象,我们都能够调用它的任意一个方法;。 这种动态获取的信息以及动态调用对象...

    Java中文参考文档(API).zip

    java.awt.dnd Drag 和 Drop 是一种直接操作动作,在许多图形用户界面系统中都会遇到它,它提供了一种机制,能够在两个与 GUI 中显示元素逻辑相关的实体之间传输信息。 java.awt.event 提供处理由 AWT 组件所激发的...

    详细介绍Java垃圾回收机制

    垃圾收集GC(Garbage Collection)是Java语言的核心技术之一,之前我们曾专门探讨过Java 7新增的垃圾回收器G1的新特性,但在JVM的内部运行机制上看,Java的垃圾回收原理与机制并未改变。垃圾收集的目的在于清除不再...

    Java反射机制——类的加载方法,创建对象,获取方法以及结构

    一、java反射机制概述 Reflection (反射)被视为动态语言的关键,为什么这么说呢,是因为它在运行时就确定下来了。反射机制允许程序在执行期间借助于Reflection ...2.反射中类的加载 2.1.1 加载  什么是类的加载呢?

Global site tag (gtag.js) - Google Analytics