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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 陈宇鹏 于 2013-4-11 14:48 编辑
  1. class Outer
  2. {
  3.         int x = 3;
  4.         void method(final int a)//这里为什么说出了栈就会释放
  5.         {
  6.                 final int y = 4;//那么这里 呢?为什么就不能够释放?
  7.                 class Inner
  8.                 {
  9.                         void function()
  10.                         {
  11.                                 System.out.println(a);
  12.                         }
  13.                 }
  14.                 new Inner().function();
  15.         }
  16. }
  17. class InnerClassDemo3
  18. {
  19.         public static void main(String[] args)
  20.         {
  21.                 Outer out = new Outer()
  22.                 out.method(7);
  23.                 out.method(8);
  24.         }
  25. }
复制代码
视频中  我一直 没办法理解是,已经final了为什么还可以更改,为什么说局部变量被final之后,被调用进栈 ,调用完成后出栈就会被释放,final难道不是将一个变量固定为一个常量么。
没有办法理解。智商真的蛮拙计

10 个回复

倒序浏览
本帖最后由 梁航斌 于 2013-4-11 12:35 编辑

你的final变量是定义在函数里面啊,只在函数内有效
回复 使用道具 举报
  1. final class A {
  2.         final int i = 10;

  3.         public final void f(final String n) {
  4.                 n = "aa"; //错误,final修饰的局部变量(形参)不能被改变
  5.         }
  6. }

  7. class B extends A {  //错误,final修饰的类不能被继承
  8.         public void f(String n) {System.out.println("11");}//错误,final修饰的方法不能被重写
  9. }

  10. public class TestFinal {
  11.         public static void main(String[] args) {
  12.                 i = 5; //错误,fianl修饰的变量不能被改变
  13.         }
  14. }
复制代码
用final关键字修饰的变量,其内容在使用的过程中是不能被改变的;对于final关键字修饰的局部变量,它也是方法的一部分,既然连方法都被内存释放了,它能不被释放吗?
这个程序中有 关于final关键字的常见错误,希望能帮到你。

回复 使用道具 举报
class Outer
{
        int x = 3;
        void method(final int a)//当函数执行完毕 那么就没有存在的意义了 所以就回收了 比如 class InnerClassDemo3 把主函数执行完毕 主函数也就被释放掉了
        {
                final int y = 4;// 这个东西是属于 method()的变量  不是属于class Inner 懂否
                class Inner
                {
                        void function()
                        {
                                System.out.println(a);
                        }
                }
                new Inner().function();
        }
}
class InnerClassDemo3
{
        public static void main(String[] args)
        {
                Outer out = new Outer()
                out.method(7);
                out.method(8);
        }
}
回复 使用道具 举报
首先说明的是,只要一个变量在函数中定义,而且不是静态的,它一定会被释放。
也就是当函数执行完成的时候,也就是函数中的内容执行完毕的时候。

final int y = 4;//那么这里 呢?为什么就不能够释放?

我疑虑,谁说这个不能够释放了?当method调用完成,它照样释放,因为栈空间已经释放了。


至于final的值为什么在这里能被修改,是因为调用函数的过程,其实就是在开辟栈空间的过程
当调用两次函数的时候,就会开辟两个栈空间,而这两个栈空间的局部变量是分离的,final的变量也是分离的,两次赋值的final值其实并不针对一个y ,而是在两个栈中的两个y


没学数据结构和编译原理吧?建议好好看看。对编程十分有利

回复 使用道具 举报
  1. /*
  2. * final 对于常量来说,意味着值不能改变,例如 final int i=100。这个i的值永远都是100。
  3. * 但是对于变量来说又不一样,只是标识这个引用不可被改变,例如 final File f=new File("c:\\test.txt");
  4. * 那么这个f一定是不能被改变的,如果f本身有方法修改其中的成员变量,例如是否可读,是允许修改的。
  5. *
  6. * 形象的比喻:一个女子定义了一个final的老公,这个老公的职业和收入都是允许改变的,只是这个女人不会换老公而已。
  7.   */

  8. class Outer
  9. {
  10.         int x = 3;
  11.         void method(final int a)//这里为什么说出了栈就会释放
  12.         {
  13.                 final int y = 4;//那么这里 呢?为什么就不能够释放?
  14.                 class Inner
  15.                 {
  16.                         void function()
  17.                         {
  18.                                 System.out.println(a);
  19.                         }
  20.                 }
  21.                 new Inner().function();
  22.         }
  23. }
  24. class InnerClassDemo3
  25. {
  26.         public static void main(String[] args)
  27.         {
  28.                 Outer out = new Outer();                //你好像漏了个分号哦。
  29.                 out.method(7);
  30.                 out.method(8);
  31.         }
  32. }
复制代码
回复 使用道具 举报
class Outer
{
        int x = 3;
        void method(final int a)//这里的a是局部变量,放在栈内存中,函数语句执行结束后,函数被释放,当然也不存在局部变量了。      
  {
                final int y = 4;// 函数执行结束,这个局部的y当然也被释放了,只是内部代码执行的整个过程中,y的值指定就不能变了,因为你并没有在新执行的函数内重新对y赋新值,因而你就以为不能释放掉 。总之一句话,不管是a还是y,你函数执行结束,这两变量默认释放。              
class Inner
                {
                        void function()
                        {
                                System.out.println(a);
                        }
                }
                new Inner().function();
        }
}
class InnerClassDemo3
{
        public static void main(String[] args)
        {
                Outer out = new Outer()
                out.method(7);
                out.method(8);
        }
}
回复 使用道具 举报
聖手`书生 发表于 2013-4-11 13:13
class Outer
{
        int x = 3;

也就是说  无论那个值在哪里只要从栈里出来就会被释放,或者说它所在的位置,只要执行完毕就会释放,是这样把。
回复 使用道具 举报
陈宇鹏 发表于 2013-4-11 14:46
也就是说  无论那个值在哪里只要从栈里出来就会被释放,或者说它所在的位置,只要执行完毕就会释放,是这 ...

不是这样子的。你现在所发的这个int x=3 是Outer类的成员变量,那么在新建对象后,x就是对象中的特有数据了,只要对象在堆内存不消失,或者说还有引用指向这个对象,x的值是能够一直堆内存中存在,且当不被final修饰时,x的值能被改变。  最后如果这个对象没有引用指向了,对象在堆内存中被当垃圾处理,x的值也随之消失了。  你要理解清楚堆和栈内存变量的特点。
回复 使用道具 举报
聖手`书生 发表于 2013-4-11 15:20
不是这样子的。你现在所发的这个int x=3 是Outer类的成员变量,那么在新建对象后,x就是对象中的特有数据 ...

这个我当然明白 我刚刚问的。说的那个值  就是说在final修饰的情况下,
比如说,该值在类中,建立对象后,执行完成就会释放,
在该类的成员方法中,只要调用完成该方法,final值就会释放,
是这样的吧。
回复 使用道具 举报
陈宇鹏 发表于 2013-4-11 15:59
这个我当然明白 我刚刚问的。说的那个值  就是说在final修饰的情况下,
比如说,该值在类中,建立对象后, ...

不是。对象的成员变量,随着对象的存在而存在。直至该对象不存在才会释放。向对象看
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马