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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

如题
public void a(final int x)
{
    final int y = 0;
}

以上两处final在运行期是否有效,换句话说x和y在运行期是否仍是终态的

9 个回复

正序浏览

   public void a(final int x)
     {
         final int y = 0;  
     }
X是形参,可以给它传入int类型的数值,传入值后X即为终态了。
而y是已经定义好的局部常量,它已经有值——0.所以运行期已经为终态了。
回复 使用道具 举报
public void a(final int x)
{
     final int y = 0;
}
final int y = 0 :在编译期就应该是终态,因为它是一个实体变量,这个应该没什么疑问;
final int x :是在运行的时候定义为终态的,因为它是一个形参,所以只有接受到实参的值时才开始定义,它定义之后,说明在 a 函数体内当次调用就不能改变 x 的值,但是重新调用函数 a 后,可以重现给 x 赋值
回复 使用道具 举报
徐炯 中级黑马 2012-5-24 13:33:11
8#
public void a(final int x)  //运行时可以传不同的int数据
     {
         final int y = 0;   
     }
y是编译常量,只要调用该方法,就不可以改变数值
x是运行常量,在调用该方法时传入一个int 整数后 x 的值就不允许修改了。
所以都终态的。
回复 使用道具 举报
y是编译常量  x是运行常量。
回复 使用道具 举报
  x ,y 已经被final 修饰过了,在调用带参方法a(); 的时候。

x 在里面传入一个int 整数后 x 的值就不允许修改了所以也是终态的。

y  在定义的时候已经赋值了 所以也是终态的。
回复 使用道具 举报
   public void a(final int x)  //运行时可以传不同的int数据
     {
         final int y = 0;  //不可以改变数值
     }
   

回复 使用道具 举报
至于如何验证局部变量还请楼主解惑。
回复 使用道具 举报
编译的时候改动y的值是肯定会编译不过的,用反射的方式绕过编译器,我查了下Method的方法中没有能得到Field类型的方法,因此用类中的final成员来模拟
class Test
{public final String s = "a";
        public static void main(String[] args)throws Exception{
                Test test = new Test();
                Field f = Test.class.getField("s");
                String oldv = (String)Test.class.getField("s").get(test);
                String newv = oldv.replace('a','b');
                f.set(test,newv);
                System.out.println(Test.class.getField("s").get(test));
}
结果输出b   分析发现newv并没有改变final中String的指向,也就是说上面这个测试意义不大。
将测试稍加改动 ,改成int
        public static void main(String[] args)throws Exception{
                Test test = new Test();
                Field f = Test.class.getField("s");
                f.set(test,3);
                System.out.println(Test.class.getField("s").get(test));
无final时,结果正常,加final,编译没问题,运行时期抛出非法访问的异常。
因此可知,在成员变量中,运行时期也不可以改变其值。
回复 使用道具 举报
x,y被final修饰在运行时期都是最终状态。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马