Java内部类

基本概念

内部类:是指把一个类的声明放到另一个类的声明中,甚至是放到一个方法内部,这样的类称为 内部类。

内部类分为 命名内部类匿名内部类

  • 命名内部类:就像平时声明一个类一样,有个名字。只是放的位置是另一个类的内部或一个方法的内部。
  • 匿名内部类:就是没有类名,一般将匿名内部类作为参数传递,也就是直接new 出某个类的子类或某个接口的实现类。两种内部类例子下面有
1、在内部类中可以访问它的外部类的所有数据成员和方法成员。通过 “OutterClass.this.” 来访问。
2、内部类中不能定义静态成员,凡是静态的都不可以定义。如果要static ,则同时必须是 final 的。
3、如果在外部类以外创建该内部类的实例,则必须先创建一个外部类的实例,然后再用这个外部类的实例对象创建内部类的实例对象。例子下面有。
4、类中的内部类的访问修饰符只能是public、protected、没有、private之一,好比在类中定义成员变量一样,还可加上abstract、final修饰符
  • 如果内部类的访问修饰符是public的,那么在本包和其他包中的类均可访问。
  • 如果内部类的访问修饰符是protected、或者没有访问修饰符的,那么只本包中的类才可访问。
  • 如果内部类的访问修饰符是private的,那么就只能在外部类中访问。
5、方法中的内部类的访问修饰符只能是 没有,就好比在方法中定义局部变量一样,但可以加上abstract、final修饰符。
  • 这种内部类只有在方法内部可见,其他任何地方均不可见。
  • 这种内部类只有先定义再使用,类中的内部类无此限制,就好比方法中的局部变量必须先定义再使用是一样的。
  • 这种内部类可以访问方法中的变量,但该变量必须是 final 的。

命名内部类 1:

package outterclass1;

/**
 * 下面的代码也许毫无意义,这里只是讨论内部类而已。
 * 
 * 
 */
public class OutterClass {
	private String name = "Outter Class Name";

	// 下面这个InnerClass命名内部类,访问修饰符可以是public、protected、没有、 private
	private class InnerClass {
		private String name = "Inner Class Name";

		/**
		 * 内部类中直接写this是指内部类,而如果先写 外部类名然后写this ,则能访问外部类的属性和方法。
		 */
		public void getOutterClassName() {
			System.out.println(OutterClass.this.name);
		}

		/**
		 * 调用外部类的方法
		 */
		public void invokeOutterClassMethod() {
			f();
		}

		/**
		 * 这里返回的是内部类的 name
		 */
		public String getName() {
			return this.name;
		}
	}

	// 在外部类中声明一个内部类类型的属性
	private InnerClass ic = new InnerClass();

	public void f() {
		System.out.println("这是 OutterClass 的方法");
	}

	public void accessInnerClass() {
		ic.invokeOutterClassMethod();
	}

	public InnerClass getIc() {
		return ic;
	}

	/**
	 * 创建一个外部类对象,并获得内部类对象,然后通过内部类对象拿到外部类的name.
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		OutterClass oc = new OutterClass();
		oc.getIc().getOutterClassName();//输出:Outter Class Name
	}
}

命名内部类 2

package outterclass2;

/**
 * 我自己很少使用内部类,暂时还没有发现内部类在实际项目中发挥的作用,尤其是下面的方法中的内部类。
 * 
 * 
 */
public class OutterClass2 {

	// 方法中的内部类的访问修饰符 :没有 、 abstract 、 final
	public void f() {

		String name = "temp variable name";

		class InnerClass {
			private String name = "Inner Class temp variable name";

			public void getOutterName() {
				System.out.println("怎么拿到上面那个name,我还真不知道,欢迎告知....");
			}
		}

		InnerClass ic = new InnerClass();
		ic.getOutterName();
	}

	public static void main(String[] args) {
		OutterClass2 oc2 = new OutterClass2();
		oc2.f(); // 输出:怎么拿到上面那个name,我还真不知道,欢迎告知....
	}
}

匿名内部类

public class OutterClass{
	/**
	 * 这里的参数可以是抽象类,具体类和接口
	 */
	public static void f(Exception e) {
		e.printStackTrace();
	}

	//这里f的参数就是一个 匿名内部类,会立即创建一个该匿名内部类的对象
	public static void testF() {
		f(new Exception() {
			@Override
			public void printStackTrace() {
				System.out.println("NND");
			}
		});
	}

	public static void main(String[] args) {
		testF(); //输出 NND
	}
}

在外部类以外的类中创建内部类的实例:

package outterclass2;

import outterclass1.OutterClass;
import outterclass1.OutterClass.InnerClass;

public class OutterClass3 {
	
	public void f(){
		OutterClass oc = new OutterClass();
		InnerClass ic = oc.new InnerClass();
	}

}

好奇试了哈,还可以在上述内部类中继续定义内部类,内部类的内部类,内部类的内部类的内部类。NND,我只想问这有何意义?

Static Nested Class

  • 在类中定义的内部类,加上static修饰,就成了Static Nested Class
    1. 如果要访问外部类的成员,则该成员必须是 static 的。
    2. 在外部类以外的其他类中创建该 static nested class的对象,外部类的对象可以不创建。如:Outter.Inner inner = new Outter.Inner();
    3. Static Nested Class 中可以定义静态成员,不需要final修饰。与上述讲的内部类不一样
    4. Static Nested Class 的访问修饰符只能是public、protected、没有、private之一,同时也可以有 abstract 、final 修饰符。也就是这个类可以同时被static和abstract修饰,这与abstract method不能同时被static 修饰是不一样的哦。
  • 在静态方法中定义的内部类,也是 Static Nested Class
    1. 这种Static Nested Class的访问修饰符只能是 没有,但可以加上abstract、final修饰符。
    2. 如果要访问外部类的成员,则该成员必须是 static 的。
    3. 如果要访问方法内的成员变量,则必须要被 final 修饰。
    4. 这种Static Nested Class只有在方法内部可见,其他任何地方均不可见。
    5. 也必须先定义,才能使用。
    6. 这种Static Nested Class中不可以定义静态成员,凡是静态的都不可以。如果要static ,则同时必须是 final 的。
  • 如果Static Nested Class的访问修饰符是public的,那么在本包和其他包中的类均访问。
  • 如果Static Nested Class的访问修饰符是protected、或者没有访问修饰符的,那么只能在本包中的类访问。
  • 如果Static Nested Class的访问修饰符是private的,那么就只能在外部类中访问。
好奇也试了哈,还可以在上述Static Nested Class 中继续定义类,类类,类的类的类。NND,我还是只想问这有何意义?

总结:
1、无论是类中的内部类,还是方法中的内部类,还是类中的Static Nested Class,还是静态方法中的Static Nested Class ,他们都可以被 abstract,final修饰。
2、无论是类中的内部类,还是类中的Static Nested Class,他们都可以被public、protected、没有、private之一修饰。
3、无论是方法中的内部类,还是静态方法中的Staitc Nested Class,他们的访问修饰符只能是 没有
4、只有类中的Static Nested Class中才能定义静态成员,同时不需要被final修饰。在其他三个类中如果要定义static成员,则必须加上final修饰。

方法中的成员变量的访问修饰符只能是 没有,只能被 final 修饰。


上一篇:SAP Spartacus routing parameter mapping介绍


下一篇:原来浏览器原生支持JS Base64编码解码 outside of the Latin1 range