`
m635674608
  • 浏览: 5052974 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

final 修饰的变量可以变

    博客分类:
  • java
 
阅读更多

final修饰的引用类型,引用不可以改变,但是它所指向的对象的内容可以改变。
public class P {
	public static void main(String[] args)throws Exception {
		final B a =new B();
		System.out.println(a.o.hashCode());
		c2(a);
		
	}
	public static void c2(B a)throws Exception{
		Field f = a.getClass().getDeclaredField("o");
		f.setAccessible(true);
		System.out.println(f.get(a).hashCode());
		f.set(a, new Object());
		System.out.println(a.o.hashCode());
	}
}
class B{
	final Object o =new Object();
}
	
  结果:
10039797
10039797
18378667

大家怎么看?
0
2
分享到:
评论
6 楼 m635674608 2013-01-14  
reason2003 写道
m635674608 写道
reason2003 写道
reason2003 写道
final B a =new B();

这里面的a 指向的是堆里面的 B 对象的实例,还不是指向 O 对象实例。
final 的意思应该是 a 的指向不能改变


B类中的final o属性,和P类型中的final a属性不是一个意思么?我这里值改了B中的final o属性,要改P中的 final a属性页是一样的啊


File的set(Object obj, Object value)方法描述

If the underlying field is final, the method throws an IllegalAccessException unless setAccessible(true) has succeeded for this Field object and the field is non-static. Setting a final field in this way is meaningful only during deserialization or reconstruction of instances of classes with blank final fields, before they are made available for access by other parts of a program. Use in any other context may have unpredictable effects, including cases in which other parts of a program continue to use the original value of this field.



我修改了一下程序,可以看出反射没有改变对象中final的值

public class B {
    final Object o =new String("1");
}


public class P {
    public static void main(String[] args)throws Exception {
        final B a =new B();
        System.out.println("o hashCode is "+a.o.hashCode());

        c2(a);

        final B a1 =new B();
        System.out.println("new a1.o hashCode is "+a1.o.hashCode());
        System.out.println("new a1.o hashCode is "+a1.o.toString());

        final B a2 =new B();
        System.out.println("new o2 hashCode is "+a2.o.hashCode());
        System.out.println("new o2 hashCode is "+a2.o.toString());
    }

    public static void c2(B a)throws Exception{
        Field f = a.getClass().getDeclaredField("o");
        f.setAccessible(true);
        System.out.println("before reflect hashcode is "+f.get(a).hashCode());
        System.out.println("after reflect value is "+f.get(a).toString());
        f.set(a, new String("2"));
        System.out.println("after reflect hashcode is "+a.o.hashCode());
        System.out.println("after reflect value is "+a.o.toString());
    }
}


o hashCode is 49
before reflect hashcode is 49
after reflect value is 1
after reflect hashcode is 50
after reflect value is 2
new a1.o hashCode is 49
new a1.o hashCode is 1
new o2 hashCode is 49
new o2 hashCode is 1






before reflect hashcode is 49 
after reflect value is 1 
after reflect hashcode is 50 
after reflect value is 2 

这不是说明已经该了吗???
5 楼 reason2003 2013-01-14  
m635674608 写道
reason2003 写道
reason2003 写道
final B a =new B();

这里面的a 指向的是堆里面的 B 对象的实例,还不是指向 O 对象实例。
final 的意思应该是 a 的指向不能改变


B类中的final o属性,和P类型中的final a属性不是一个意思么?我这里值改了B中的final o属性,要改P中的 final a属性页是一样的啊


File的set(Object obj, Object value)方法描述

If the underlying field is final, the method throws an IllegalAccessException unless setAccessible(true) has succeeded for this Field object and the field is non-static. Setting a final field in this way is meaningful only during deserialization or reconstruction of instances of classes with blank final fields, before they are made available for access by other parts of a program. Use in any other context may have unpredictable effects, including cases in which other parts of a program continue to use the original value of this field.



我修改了一下程序,可以看出反射没有改变对象中final的值

public class B {
    final Object o =new String("1");
}


public class P {
    public static void main(String[] args)throws Exception {
        final B a =new B();
        System.out.println("o hashCode is "+a.o.hashCode());

        c2(a);

        final B a1 =new B();
        System.out.println("new a1.o hashCode is "+a1.o.hashCode());
        System.out.println("new a1.o hashCode is "+a1.o.toString());

        final B a2 =new B();
        System.out.println("new o2 hashCode is "+a2.o.hashCode());
        System.out.println("new o2 hashCode is "+a2.o.toString());
    }

    public static void c2(B a)throws Exception{
        Field f = a.getClass().getDeclaredField("o");
        f.setAccessible(true);
        System.out.println("before reflect hashcode is "+f.get(a).hashCode());
        System.out.println("after reflect value is "+f.get(a).toString());
        f.set(a, new String("2"));
        System.out.println("after reflect hashcode is "+a.o.hashCode());
        System.out.println("after reflect value is "+a.o.toString());
    }
}


o hashCode is 49
before reflect hashcode is 49
after reflect value is 1
after reflect hashcode is 50
after reflect value is 2
new a1.o hashCode is 49
new a1.o hashCode is 1
new o2 hashCode is 49
new o2 hashCode is 1



4 楼 reason2003 2013-01-14  
m635674608 写道
reason2003 写道
reason2003 写道
final B a =new B();

这里面的a 指向的是堆里面的 B 对象的实例,还不是指向 O 对象实例。
final 的意思应该是 a 的指向不能改变


B类中的final o属性,和P类型中的final a属性不是一个意思么?我这里值改了B中的final o属性,要改P中的 final a属性页是一样的啊


AccessibleObject setAccessible方法

Set the accessible flag for this object to the indicated boolean value. A value of true indicates that the reflected object should suppress Java language access checking when it is used. A value of false indicates that the reflected object should enforce Java language access checks.
3 楼 m635674608 2013-01-14  
reason2003 写道
reason2003 写道
final B a =new B();

这里面的a 指向的是堆里面的 B 对象的实例,还不是指向 O 对象实例。
final 的意思应该是 a 的指向不能改变


B类中的final o属性,和P类型中的final a属性不是一个意思么?我这里值改了B中的final o属性,要改P中的 final a属性页是一样的啊
2 楼 reason2003 2013-01-14  
reason2003 写道
final B a =new B();

这里面的a 指向的是堆里面的 B 对象的实例,还不是指向 O 对象实例。
final 的意思应该是 a 的指向不能改变
1 楼 reason2003 2013-01-14  
final B a =new B();

相关推荐

    final修饰成员变量和局部变量.md

    本文章是关于final部分知识所作的自我总结,内容为final对成员变量和局部变量修饰的简要解答,除了对自我java学习的一个小结,也希望能够帮助到在java路上对该内容疑惑的同行

    final修饰类

    **final 修饰变量** 1. **final 常量**:当`final`修饰一个成员变量(属性)时,它就变成了一个常量,一旦赋值就不能再次更改。对于基本类型的变量,这意味着值不能改变。对于引用类型的变量,虽然引用本身不能改变...

    Java中局部内部类可以访问它所在方法中定义的final修饰的局部变量的合理解释.doc

    Java 中局部内部类可以访问它所在方法中定义的 final 修饰的局部变量的合理解释 在 Java 中,局部内部类可以访问它所在方法中定义的 final 修饰的局部变量,这是一个非常重要的知识点。这是因为 JVM 在编译时会将 ...

    day11 05 final关键字用于修饰成员变量

    day11_05_final关键字用于修饰成员变量

    java final变量详解

    Java 中的 final 变量是指不能被改变的变量,它有三个方面的作用:修饰变量、修饰方法和修饰类。在 Java 中,final 变量是一种常量,它只能被赋值一次,赋值后值不再改变。 final 变量的使用方法有多种,例如在变量...

    动力节点老杜Java基础入门视频教程——final修饰局部变量

    012-JavaSE进阶-final修饰局部变量

    java面向对象之final修饰符.docx

    一、final修饰变量 1. 当final修饰成员变量(类变量和实例变量)时,这个变量一旦被赋值后,就不能再被修改。对于类变量,final可以在静态初始化块中指定初始值或声明时直接赋值;对于实例变量,可以在非静态初始化...

    final修饰符与类型转化

    对于实例变量,必须在构造器中或者初始化块中赋值,对于静态`final`变量,可以在类加载时或静态初始化块中赋值。`final`变量在多线程环境中特别有用,因为它确保了线程安全。 2. 类型转化: - 自动类型转化(隐式...

    【Java语言基础】final关键字

    final修饰变量时,表示该变量一旦获得了初始值之后就不可被改变,final既可修饰成员变量(包括类变量和实例变量),也可以修饰局部变量,形参。 final修饰成员变量 类变量:当类初始化时,系统会为类变量分配内存,...

    局部变量用final的讨论

    标题中的“局部变量用final”的讨论主要聚焦于Java编程语言中的一个特性,即使用`final`关键字修饰局部变量。在Java中,`final`关键字有多种用途,包括但不限于定义不可变对象、创建常量以及限制变量的赋值次数。在...

    final变量.

    - **修饰变量**:`final`成员变量一旦赋值就不能再次改变,常用于声明常量。静态`final`变量在类加载时初始化,而非静态`final`变量则在对象创建时初始化。 - **修饰方法**:`final`方法不能被子类覆盖,但可以被...

    Java软件开发实战 Java基础与案例开发详解 6-6 final修饰符 共7页.pdf

    final修饰变量 - **定义与作用**:当`final`修饰一个变量时,意味着该变量的值一旦被初始化之后就无法改变。这种变量通常被称为常量。 - **语法示例**: ```java final int PI = 31415; ``` - **注意事项**: ...

    java_中的_final_变量[文].pdf

    在Java编程语言中,`final`关键字扮演着重要的角色,它用于声明不可变的变量、方法和类。理解`final`的关键在于其不可变性,这有助于提高程序的效率、稳定性和设计规范。 首先,`final`变量表示常量,一旦赋值后就...

    计算机后端-Java-Java核心基础-第15章 面向对象07 26. final修饰局部变量.avi

    计算机后端-Java-Java核心基础-第15章 面向对象07 26. final修饰局部变量.avi

    JavaSE之final关键字与成员变量的类型

    3. **final修饰局部变量** `final`关键字也可以修饰局部变量,这意味着一旦给局部变量赋值后,它的值就不可改变。例如: ```java public class DemoFinal { public static void main(String[] args) { final ...

    day11 04 final关键字用于修饰局部变量

    day11_04_final关键字用于修饰局部变量

    Static和Final修饰类属性变量及初始化

    1.static修饰一个属性字段,那么这个属性字段将成为类本身的资源,public修饰为共有的,可以在类的外部通过test.a来访问此属性;在类内部任何地方可以使用.如果被修饰为private私有,那么只能在类内部使用.

    java中final修饰符的使用方法

    1. `final`修饰变量: 当`final`修饰一个变量时,它表示该变量一旦被赋值后就不能再次改变。这分为两种情况: - **实例变量**:如果`final`修饰的是实例变量,那么必须在声明时、非静态初始化块或构造器中为其...

    Java并发--final关键字.docx

    **一、final修饰变量** 1. **成员变量**:成员变量分为类变量(`static`修饰)和实例变量。对于类变量,可以在声明时直接初始化或在静态初始化块中赋值,两者选其一。实例变量则可以在声明时、非静态初始化块中或...

Global site tag (gtag.js) - Google Analytics