黑马程序员技术交流社区

标题: 内部类只能访问被finnal修饰的局部变量这是为什么? [打印本页]

作者: 丁朋    时间: 2012-7-16 17:43
标题: 内部类只能访问被finnal修饰的局部变量这是为什么?
今天在内部类处遇到一个问题
class Outer
{
int x = 3;

void method(final int a)//这里为什么只能传进来一个常量,不能传进来变量吗?
{
  final int y = 4;//为啥这里只能是finnal,老师说这是规则,只有记住它吗?不理解怎么回事
  class Inner
  {
   void function()
   {
    System.out.println(y);
   }
  }

  new Inner().function();
  
}
}


class  InnerClassDemo3
{
public static void main(String[] args)
{
  Outer out = new Outer();
  out.method(7);
  out.method(8);
}
}


作者: 陈世涛    时间: 2012-7-16 17:50
楼主看样子对final不太理解。
对于final有一下作用:
2、Final的特点:
1、final是一个修饰符,可以修饰类、方法、变量(成员变量、局部变量)
2、Final修饰的类不可以被继承。
3、Final修饰的方法不可以被覆盖。
4、Final修饰的变量是一个常量,只能被赋值一次。是为了增强阅读性,只要数据是固定的,
    就将这个数据用一个名称来表示,并用final修饰。常量名称都是大写字母,多个单词组
    成时用下划线来分隔。
代码体现:
   Eg:
   Class Zi
{
        Static final int num=90;
        //必须对变量进行初始化,不知道要最终化哪个值,
           所以必须对它进行初始化。加静态也是一样的,同样的道理,并且被初始化,
           此时静态和final没有必然的联系。当变量被final修饰时,说明变量已经是一个常量值,
            此时不能被修饰,可以用static来修饰。
        Public stati double PI=3.14;
        Void method()
        {
                Final int x=4;
                X=8;
                Sop(num);
                     //既然是在操作一个固定的值。为什么不把4直接写在此处,
        如果这样做的的话,阅读性极差,你根本就不知道它所代表什么?
       为了增强阅读性,此时数据是不变化的,所以我们需要给它起个名字,
       并且用final来修饰。这样的话它也是固定的不变的。
      注意:被final修饰的数值只能被覆写一次,并且修饰的常量名全部大写,
      多个单词组成时用下划线进行分隔。Eg:final int PERSON_AGE=4;
        }
}
希望对楼主有所帮助。
作者: 全海波    时间: 2012-7-16 17:54
  1. class Outer
  2. {
  3. int x = 3;
  4. void method(final int a)//这里为什么只能传进来一个常量,不能传进来变量吗?
  5. {
  6. //第一个问题:final只能用于常量的修饰,这里传一个变量进来是不行的,因为变量是随时变化的,用final修饰的数只能赋值一次,你想想,这不矛盾吗?
  7.   final int y = 4;//为啥这里只能是finnal,老师说这是规则,只有记住它吗?不理解怎么回事
  8. //至于第二个问题:你这里可以不用final修饰,这又不是接口,如果是接口的,那么就应该要了,而在接口中,你也可以不加final修饰,因为在接口中,当你没有加final的时候,系统会自动给你加上的
  9.   class Inner
  10.   {
  11.    void function()
  12.    {
  13.     System.out.println(y);
  14.    }
  15.   }

  16.   new Inner().function();
  17.   
  18. }
  19. }

  20. class  InnerClassDemo3
  21. {
  22. public static void main(String[] args)
  23. {
  24.   Outer out = new Outer();
  25.   out.method(7);
  26.   out.method(8);
  27. }
  28. }

复制代码

作者: 曹魁    时间: 2012-7-16 17:59
对于内部类,首先你要了解内部类的访问规则,
1,内部类可以直接访问外部类中的成员。,
2,外部类需要创建内部类对象才可以访问内部类中的成员。

void method(final int a)//这里为什么只能传进来一个常量,不能传进来变量吗?
//这个就需要知道final的用法:
1,final是一个修饰符,既可以修饰类,又可以修饰方法,还可以修饰变量。
2,final修饰的类不可以被继承。
3,final修饰的方法不可以被覆盖。
4,final修饰的变量是一个常量,只能赋值一次。
所以被final修饰过后的变量相当于常量,数值是不能改变的!


final int y = 4;//为啥这里只能是finnal,老师说这是规则,只有记住它吗?不理解怎么回事
这个问题,暂时还有点不理解,相信应该有高人会指点的!

希望对你有所帮助!!!
作者: 游兴钟    时间: 2012-7-16 18:39
本帖最后由 achilles 于 2012-7-16 18:45 编辑

class Outer
{
int x = 3;
void method(int a)//这里只是一个局部变量,不涉及内部类的访问是可以不用加final修饰的
{
  final int y = 4;//方法中定义的内部类编译之后,也会出现与外部类不同的独自的字节码,他们有各自的成员变量和方法。换句话说就是会出现两个class
//文件。在内存中,类的属性会被分配到栈中的。当调用结束的时候就会退栈,也就是说在内存中这个属性就消失了。内部类也是类,只有在内存中对
//他的引用消失了内部类才会死亡。也就是说局部类的生命周期要比类的局部变量(这里的y变量)的生命周期要长。所以内部类不可能调用类中已经结束
//调用的属性(这里的变量y)。所以要在方法中的变量前加final,当某一属性加此关键词后就成为常量了,而常量的生命周期为程序的整个执行期间。


  class Inner
  {
   void function()
   {
    System.out.println(y);
   }
  }

  new Inner().function();
  
}
}

class  InnerClassDemo3
{
public static void main(String[] args)
{
  Outer out = new Outer();
  out.method(7);
  out.method(8);
}
}
作者: 陆强强    时间: 2012-7-16 19:33
内部类也有字节码也会生成class文件。
但一般方法是随着对象消失而消失的,这时内部类还在,他就访问不到局部变量Y;
为了让内部类可以一直访问到他们,只有让变量和参数变成常量,随着外部类的消失而消失,这样就能一直访问到他们




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2