java关于内部类的一些使用跟限制记录

内部类,java类库经常使用的一种形式,这次有时间,记载一下,以下全是代码,描述全在注释当中,可以直接复制代码,进行测试

 

----------------------------------我是分割线------------------------------------

 

public class InnerClass {

	private String msg = "外部类private修饰的字符串";
	public String msg1 = "外部类public修饰的字符串";
	static int number = 0;
	final double d = 1.2d;
	static final float F = 1.3f;


	/**
		普通的内部类;
		 限制跟使用如下:
		  1:内部类可以使用外部类的全局变量
	      2:内部类内,不能定义静态方法跟静态变量,因为内部类是依赖外部类存在的
	 		只有实例化外部类了,JVM才会去加载内部类,
	 		而静态方法跟静态变量都是依赖类存在的,
	 	  3:当内部类修改了外部类的全局变量,外部类的全局变量也会被修改
	      4:内部类中,不允许在定义静态内部类,但是可以接着定义非静态内部类
	      5:内部类也可以继承,实现接口
	 */
	public class RuleInnerClass{

		/*
			但是可以定义普通的内部类
		 */
		class InnerInnerClass{

		}

		/*
			内部内中,不允许定义静态内部类
		 */
		//static class StaticInnerClass{
		//
		//}

		/*
		 *	编译器会报错,普通内部类不允许定义静态变量
		 */
		//static int a = 0;

		/*
			也不允许定义静态方法
		 */
		//public static void printmsg(){
		//
		//}

		public void print(){
			System.out.println(msg);
			System.out.println(msg1);
			System.out.println(number);
			System.out.println(d);
			System.out.println(F);
		}

		/**
			构建私有内部类实例,调用其方法
		 */
		public void printPrivateInnerClass(){
			PrivateInnerClass privateInnerClass = new PrivateInnerClass();
			privateInnerClass.print();
		}

	}

	/**
		私有内部类的功能限制跟普通内部类一样
	 	不过私有的内部类,不能在外部类以外进行实例化
	 */
	private class PrivateInnerClass{
		public void print(){
			System.out.println(msg);
			System.out.println(msg1);
			System.out.println(number);
			System.out.println(d);
			System.out.println(F);
		}
	}

	/**
	 	 静态内部类;
		 限制跟使用如下:
		 1:静态内部类只能使用外部类的静态变量
		 2:静态内部类内,可以定义非静态变量跟静态变量以及静态方法,因为静态内部类不依赖于外部类的实例
	     3:静态内部类也可以实现接口,跟继承类
	 	 4:静态内部类内部,还可以定义静态内部类跟非静态内部类
	 */
	static class StaticInnerClass implements Contents{

		int a = 0;
		static int i = 1;

		class IsNotStaticInnerInnerClass{

		}

		static class StaticInnerInnerClass{

		}

		public static void printStatic(){
			System.out.println("静态内部类的静态方法");
		}
		public void print(){
			/*
				静态内部类里面,不允许调用外部类的非静态变量
			 */
			//System.out.println(msg);
			System.out.println(number);
			System.out.println(F);
			System.out.println(a);
			System.out.println(i);
		}
	}

	/**
	 * 	局部内部类限制跟普通内部类差不多
	 * 	1:都是不能定义静态属性跟方法也不能定义静态内部类
	 * 	2:局部内部类可以调用外部类的所有全局变量
	 * 	3:局部内部类的内部类可以定义普通局部内部类
	 * 	4:局部内部类调用局部变量,必须是final修饰的,因为局部变量在方法调用结束就会销毁,但是局部内部类不会销毁
	 * 	5:局部内部类可以继承跟实现接口
	 * 	6:局部内部类不能当做返回参数返回,如果要返回局部内部类,实现一个接口或者继承一个类,通过向上转型返回
	 *	7:方法外局部内部类引用,只能通过继承类或者实现接口向上转型返回,因为局部内部类的作用域只能限于方法内,所以不能再方法外进行实例化
	 */
	public Contents getLocalInnerClass(){

		final String methodFiled = "局部变量";

		/*
			不能定义一个局部静态类
		 */
		//static class LocalInnerStaticClass{
		//
		//}
		/*
			局部内部类,不能使用修饰符
		 */
		class LocalInnerClass implements Contents{

			int localMenthodFiled = 0;

			/*
				不能定义静态变量
			 */
			//static int a = 0;

			public void print(){
				System.out.println(localMenthodFiled);
				System.out.println(number);
				System.out.println(msg);
				System.out.println(methodFiled);
			}

			/*
				局部内部类也不能定义静态方法
			 */
			//public static void staticPrint(){
			//
			//}

			/*
				也不能定义静态内部类
			 */
			//static class LocalStaticClass{
			//
			//}
		}
		return new LocalInnerClass();
	}

	/**
	 * 	匿名内部类限制跟局部内部类差不多
	 * 	1:都是不能定义静态属性跟方法也不能定义静态内部类
	 * 	2:匿名内部类可以调用外部类的所有全局变量
	 * 	3:匿名内部类的内部类可以定义普通局部内部类
	 * 	4:匿名内部类调用局部变量,必须是final修饰的,因为局部变量在方法调用结束就会销毁,但是匿名内部类不会销毁
	 * 	5:匿名必须实现一个接口,或者集成一个类
	 * 	6:匿名内部类不能当做返回参数返回(因为它压根就没名字),但是可以返回匿名内部类实现的接口或者继承类,从而返回匿名内部类的引用
	 */
	public Contents getContents(){

		final int w = 1;

		return new Contents() {
			int q = 0;
			/*
				不能定义静态变量
			 */
			//static int s = 2;
			@Override
			public void print() {
				/*
					可以调用外部类的所有变量
				 */
				System.out.println(msg);
				System.out.println(msg1);
				System.out.println(number);
				System.out.println(d);
				System.out.println(F);

				/*
					调用局部变量,必须是final修饰
				 */
				System.out.println(w);


				System.out.println(q);
				System.out.println("我是匿名内部类");
			}

			/*
				不能定义静态方法
			 */
			//public static void staticPrint(){
			//
			//}

			/*
				不能定义静态内部类
			 */
			//static class StaticClass{
			//
			//}

			/*
				可以定义非静态内部类
			 */
			class IsNotStaticClass{

			}
		};
	}
}

 

 

public class InnerTest {


	public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {


		InnerClass innerClass = new InnerClass();
		/*
			常规内部类构建方法有两种
			1: 是通过外部类.new 内部类类名来创建
			2: 是通过反射创建
		 */

		/**
		 *  普通创建内部类的方法
		 */
		InnerClass.RuleInnerClass ruleInnerClass = innerClass.new RuleInnerClass();
		ruleInnerClass.print();
		System.out.println("--------------------------------------");
		ruleInnerClass.printPrivateInnerClass();

		/**
		 *  反射创建内部类的方法
		 *  需要注意的是,通过反射创建内部类,地址是报名.外部类类名$内部类类名
		 *  而且构建内部类,需要传入一个外部类的引用,
		 *  所以必须通过Constructor类的newInstance方法构建内部类
		 */
		Class c =Class.forName("com.demo.innerClass.InnerClass$RuleInnerClass");
		System.out.println("我需要一个外部对象:"+ Arrays.toString(c.getDeclaredConstructors()));
		Constructor constructor = c.getConstructor(InnerClass.class);
		InnerClass.RuleInnerClass o = (InnerClass.RuleInnerClass)constructor.newInstance(new InnerClass());
		o.print();

		System.out.println("--------------------------------------");

		/*
		 	创建静态内部类,不需要外部类的实例,可以通过 new 外部类.静态内部类进行创建
		 	调用静态内部类的静态方法,是通过 外部类.静态内部类.静态方法就可以调用
		 	调用静态内部类的静态变量,同理,只不过是把静态方法,变为静态变量
		 */
		InnerClass.StaticInnerClass staticInnerClass = new InnerClass.StaticInnerClass();
		staticInnerClass.print();
		InnerClass.StaticInnerClass.printStatic();

		System.out.println("--------------------------------------");


		/*
			方法外创建局部内部类,只能通过继承类或者实现接口向上转型返回
			因为局部内部类的作用域只能限于方法内
		 */
		Contents contents = innerClass.getLocalInnerClass();
		contents.print();


		System.out.println("--------------------------------------");

		/*
			匿名内部类,只能通过向上转型返回它的实例引用
		 */
		Contents contents1 = innerClass.getContents();
		contents1.print();
	}

}

 

 

到这,文章就结束了!

以上,均为本人测试而得出的结果,可能会有出入,或者错误,欢迎指正

欢迎转载,请注明出处跟作者,谢谢!

转载于:https://my.oschina.net/u/2278977/blog/841627

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值