A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 奥特曼爱小怪兽 中级黑马   /  2012-4-23 16:15  /  1744 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

看了视频和java核心技术,对局部内部类的访问权限的说明都是,对于块中的局部变量,可以访问,但是必须是被声明为final类型的局部变量,可是下面的代码中却可以访问不是final修饰的局部变量。这是为什么呢。
  1. public class OutClass2{
  2.         public void show(){
  3.                 class InnerClass{
  4.                         private int a ;
  5.                         public InnerClass(int a){
  6.                                 this.a = a;
  7.                         }
  8.                         public void show(){
  9.                                 System.out.println(a);
  10.                         }
  11.                 }
  12.                 int a = 2;
  13.                 new InnerClass(a).show();
  14.         }
  15.         
  16.         public static void main(String[] args){
  17.                 new OutClass2().show();
  18.         }
  19.         
  20. }
复制代码
运行结果:

捕获1.PNG (3.5 KB, 下载次数: 23)

捕获1.PNG

4 个回复

倒序浏览
本帖最后由 真真姐 于 2012-10-21 14:44 编辑

这个方法完全是正确的,先分析下概念啊
内部类有两种:实例内部类、静态内部类 自己总了些便于你理解!
[实例内部类中]
    A:不论外部类的成员的访问修饰符是哪一种,内部类都可以访问
    B:一个外部类的实例可以对应很多内部类实例。在外部类中不能直接访问内部类的成员,必须通过内部类的实例去访问才可以
[静态内部类中]
    A:静态内部类可以直接访问外部类的静态成员,如果访问外部类的实例成员,就必须通过外部类的实例去访问。在创建内部类的实例的时候,不必创建外部类的实例.。
           B:外部类可以通过完整的类名来直接访问静态内部类的静态成员,如果要访问静态内部类的非静态成员则需要创建静态内部类的一个实例才行

在实例化内部类InnerClass的时候,是在内部类以外的方法中,a是作为参数传递进去的,就像是传值一样,而在内部类里面使用的是自己的变量
不好理解的话给你个示例把
1、public InnerClass(int m){}  2、public InnerClass(int n){} 3、 public InnerClass(int x){}  4、public InnerClass(int y){}
这个方法的参数名字是自己定义的一个名字而已,写什么都不会报错
所以执行当然没问题了,但是如果不是当作传递参数,而是直接作为变量来使用的话了,那么就需要按照视频上面得来
public voidshow()
           {
              
              final int  a = 5; //去掉final就会报错的啊 ,同时把a的初始化放到InnerClass类的后面执行也出错                        

              class InnerClass
                  {
                     private int b;
                     
                     public InnerClass(int m)   //  注意别让你的方法的参数成了障眼法,这里换成了m
                         {
                            this.b = a;
                            System.out.println("是啊" + a + b);
                         }
                     public void show()
                         {
                            System.out.println(b);
                         }
                  }
              new InnerClass(b ).show();
           }

手工制作,加完整分析,够给力把~


                                
回复 使用道具 举报
了解了 非常谢谢
回复 使用道具 举报
本帖最后由 王明(1988) 于 2012-4-23 17:16 编辑

嗯,你的问题很不错哦,不过你的代码不是验证局部内部类只能访问外部类成员方法中的final类型变量的例子。
因为你在
int a = 2;
new InnerClass(a).show();
这里将2传进去,局部内部类当然能得到并打印出来啊。。。
我自己写个例子你看下,验证局部内部类只能访问final类型的局部变量。
代码:
  1. package com.heima;

  2. public class LocalInnerClassTest {
  3.         //局部内部类要访问的x为final,去掉final你是编译通不过的。
  4.         public void defineInnerClass(final int x) {
  5.                 //局部内部类
  6.                 class MyLocalInnerClass {
  7.                         public void doSomething() {
  8.                                 System.out.println("局部内部类MyLocalInnerClass打印的局部变量X为:"+x);
  9.                         }
  10.                 }
  11.                 new MyLocalInnerClass().doSomething();
  12.         }
  13.         
  14.         public static void main(String[] args) {
  15.                 LocalInnerClassTest lct = new LocalInnerClassTest();
  16.                 lct.defineInnerClass(5);
  17.         }
  18. }
复制代码
输出结果为:

如果将final去掉编译是错误的。
图为:

回复 使用道具 举报
本帖最后由 王明(1988) 于 2012-4-23 17:24 编辑

int x 是局部变量,因为java底层的机制不能存取本地变量,这样导致内部类,没有办法取过来,所以java用了一个小聪明,直接把本地变量的refrenece拷贝到内部类。
因为这个小聪明,一般容易让人误解。所以他在编译器里面,加上了一个final,让你不要改变这个值,你只读不能存,这样感觉就好了。
2楼哥们分析的不错哦,热心人不止我一个啊。{:soso_e100:}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马