内部类详解

1、什么是内部类?

  定义:将一个类定义在另一个类的里面,对里面那个类就称为内部类(也称为内置类,嵌套类)。例如,把类B定义在类A里面,B就被称为A的内部类。

  示例如下:

<span style="font-size:14px;">//定义外部类
class Outer
{
	private int num = 10;

	//定义内部类
	class Inner
	{
		public void show()
		{
			System.out.println(num);
		}
	}
}</span>
2、内部类的作用及访问特点?

  作用:我们知道,如果一个类中定义变量用private修饰,那么外部是不能够直接访问的,这种情况下,如果我们要访问,就可以用到内部类。

  访问特点:内部类可以直接访问外部类中的成员,包括私有成员;而外部类要访问内部类中的成员必须要建立内部类的对象。

3、内部类的分类?

  按照内部类的定义位置,可以分为成员内部类(定义在外部类的成员位置)、局部内部类(定义在外部类的方法里边)。 

  (1)成员内部类:

<span style="font-size:14px;">//定义外部类
class Outer
{
	private int num = 10;

	//定义内部类
	class Inner
	{
		public void show()
		{
			System.out.println(num);
		}
	}

}</span>
  以上就是一个成员内部类,它定义在了成员位置(就是和成员变量、成员方法等相同的位置),如果我们要实现对内部类的访问,那么只能是:

<span style="font-size:14px;">class InnerTest 
{
	public static void main(String[] args) 
	{
	
		//我能不能直接使用Inner类呢?显然是不可以的,因为内部类定义在其它类里边,而虚拟机是看不到类里边的东西的
		//Inner i = new Inner(); //会报出找不到该类路径的错误
		//i.show();

		//所以,正确的格式是:外部类名.内部类名 变量 = 外部类对象.内部类对象; 我们需要经过外部类的限定才能访问内部类
		Outer.Inner oi = new Outer().new Inner();
		oi.show();
	}
}</span>
  值得注意的是,在外面创建内部类对象格式须为:外部类名.内部类名 变量 = 外部类对象().内部类对象();。

  (2)局部内部类:

<span style="font-size:14px;">//定义外部类
class Outer
{
	public void method(){
		final int num = 10;

		//定义局部内部类
		class Inner{
			public void show(){
				System.out.println(num);
			}
		}
		//创建对象
		Inner i = new Inner();
		i.show();
	}
}</span>
  注意:如果用成员内部类的方式:外部类名.内部类名 变量 = 外部类对象.内部类对象;来创建局部内部类是不可以的,因为虚拟机也看不到方法里边的东西,无法提供路径,所以必须在方法里边来创建局部内部类的对象,此外局部内部类如果访问局部变量(例如上边的num),局部变量必须被final修饰。

  那么为什么必须被final修饰呢?

  因为局部变量存储在栈内存中,而栈内存最大的特点是数据使用完后立马消失,所以局部变量会在方法调用完毕后,立马消失。而局部内部类虽然也在方法中,但是new出的对象是存在堆内存中的,所以局部内部类所在的方法调用完毕消失后,局部内部类new出的对象依然存在,所以内部类中定义的方法依然存在,方法依然存在就要要求方法所用到的局部变量存在,所以局部内部类访问的局部变量就不能是使用完后消失的变量,所以要求其被final修饰,作为常量储存在方法区中,不会消失。也就是说,如果有地方使用着局部变量,当方法消失后,这个变量还必须存在。所以,为了延长局部变量的生命周期,就加final修饰了。

4、内部类的常用修饰符?

  内部类的常用修饰符为private、static。

  (1)private:为了安全考虑。如果将外部类视为body的话,内部类就可以看为这个body的心脏,我们当然不会希望外部可以随意的访问我们的心脏,那么太不安全了,所以我们需要对内部类进行private修饰。那么这个时候,我们只能将对内部类的访问交给外部类的一个方法,然后将这个方法做成public,提供给外部访问。例如:

<span style="font-size:14px;">//定义外部类
class Outer
{
	private int num = 10;

	//定义内部类
	private class Inner
	{
		public void show()
		{
			System.out.println(num);
		}
	}
	//将对内部类的访问交给method方法来做
	public void method()
	{
		Inner i = new Inner();
		i.show();
	}
}</span>
  (2)static:为了调用方便考虑。用静态修饰过的方法和变量可以直接通过类名调用,但是如果成员内部类内部类中方法被static修饰,那么这个成员内部类必须被static修饰,为什么呢?

  因为成员内部类定义在外部类的成员位置,可以看成是外部类的成员,是可以被静态修饰的。而静态是随着类的加载而加载的,如果内部类的静态方法被加载时,发现内部类却因为没有被static修饰而无法加载时就会报错。

  另外,被static修饰的成员内部类,创建对象的方法就应该是:外部类名.内部类名 变量 = new 外部类名.内部类名();(对比原先的是:new 外部类名().内部类名();),因为被静态修饰,只能通过外部类类名来调用,不能通过外部类对象来调用。

  小结:内部类就是定义在类里边的类,是类中类。使用内部类要清楚内部类的作用、访问特点和限制修饰符的各种作用。

内部类详解_第1张图片

你可能感兴趣的:(java,内部类,成员内部类,局部内部类,嵌套类)