最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java反射如何修改private final成員變量值

 更新時間:2019年07月02日 16:48:21   作者:單行線的旋律  
這篇文章主要介紹了Java反射如何修改private final成員變量值,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

大家都知道使用java反射可以在運行時動態(tài)改變對象的行為,甚至是private final的成員變量,但并不是所有情況下,都可以修改成員變量。今天就舉幾個小例子說明。

基本數(shù)據(jù)類型

/**
 * @author Cool-Coding 2018/5/15
 */
public class ReflectionUsage {private final int age=18;
 public int getAge(){
  return age;
 }
}

測試代碼:

import java.lang.reflect.Field;
/**
 * @author Cool-Coding 2018/5/15
 */
public class ReflectionTest {
 public static void main(String[] args){
  try {
   Class reflectionUsage = Class.forName("practise.practise.ReflectionUsage");
   ReflectionUsage o = (ReflectionUsage)reflectionUsage.newInstance();
   Field age = reflectionUsage.getDeclaredField("age");
   age.setAccessible(true);
   age.set(o,68);
   age.setAccessible(false);
   System.out.println(o.getAge());
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  } catch (NoSuchFieldException e) {
   e.printStackTrace();
  }catch (IllegalAccessException | InstantiationException e){
  }
 }
}

運行結(jié)果:18

此時無法修改成員變量age.

如果將初始化age放到構(gòu)造函數(shù)中會如何呢:

/**
 * @author Cool-Coding 2018/5/15
 */
public class ReflectionUsage {private final int age;
 public ReflectionUsage(){
  this.age=18;
 }
 public int getAge(){
  return age;
 }
}

再執(zhí)行RefectionTest會發(fā)生什么呢?會發(fā)現(xiàn)結(jié)果變成了68。

為什么會發(fā)生這種情形呢?看一下這兩個情況下生成的class文件有什么不同:

直接初始化:

public class ReflectionUsage {
 private final int age = 18;
 public ReflectionUsage() {
 }
 public int getAge() {
  return 18;
 }
}

構(gòu)造函數(shù)中初始化:

public class ReflectionUsage {
 private final int age = 18;
 public ReflectionUsage() {
 }
 public int getAge() {
  return this.age;
 }
}

可以看出如果直接初始化時,經(jīng)過編譯后getAge方法直接返回常量值,而在構(gòu)造函數(shù)中初始化時,返回的是this.age變量的值。

String類型

/**
 * @author Cool-Coding 2018/5/15
 */
public class ReflectionUsage {
 private final String reflectionString="reflectionString";
 public String getReflectionString(){
  return reflectionString;
 }
}

測試代碼:

import java.lang.reflect.Field;
/**
 * @author Cool-Coding 2018/5/15
 */
public class ReflectionTest {
 public static void main(String[] args){
  try {
   Class reflectionUsage = Class.forName("practise.practise.ReflectionUsage");
   ReflectionUsage o = (ReflectionUsage)reflectionUsage.newInstance();
   Field reflectionString = reflectionUsage.getDeclaredField("reflectionString");
   reflectionString.setAccessible(true);
   reflectionString.set(o,"newReflectionString");
   reflectionString.setAccessible(false);
   System.out.println(o.getReflectionString());
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  } catch (NoSuchFieldException e) {
   e.printStackTrace();
  }catch (IllegalAccessException | InstantiationException e){
  }
 }
}

運行結(jié)果:reflectionString

如果將初始化reflectionString放到構(gòu)造函數(shù)中又如何呢?

/**
 * @author Cool-Coding 2018/5/15
 */
public class ReflectionUsage {
 private final String reflectionString;
 public ReflectionUsage(){
  this.reflectionString="reflectionString";
 }
 public String getReflectionString(){
  return reflectionString;
 }
}

運行結(jié)果:newReflectionString

為什么運行結(jié)果不同呢,來看下class文件:

直接初始化:

public class ReflectionUsage {
 private final String reflectionString = "reflectionString";
 public ReflectionUsage() {
 }
 public String getReflectionString() {
  return "reflectionString";
 }
}

構(gòu)造函數(shù)中初始化:

public class ReflectionUsage {
 private final String reflectionString = "reflectionString";
 public ReflectionUsage() {
 }
 public String getReflectionString() {
  return this.reflectionString;
 }
}

可以看出跟基本類型相似,直接初始化時,編譯器會將reflectionString出現(xiàn)的地方,替換成常量值,而構(gòu)造函數(shù)中初始化不替換。

Integer類型

/**
 * @author Cool-Coding 2018/5/15
 */
public class ReflectionUsage {
 private final Integer age=18;
 public Integer getAge(){
  return age;
 }
}

測試代碼:

import java.lang.reflect.Field;
/**
 * @author Cool-Coding 2018/5/15
 */
public class ReflectionTest {
 public static void main(String[] args){
  try {
   Class reflectionUsage = Class.forName("practise.practise.ReflectionUsage");
   ReflectionUsage o = (ReflectionUsage)reflectionUsage.newInstance();
   Field reflectionString = reflectionUsage.getDeclaredField("age");
   reflectionString.setAccessible(true);
   reflectionString.set(o,68);
   reflectionString.setAccessible(false);
   System.out.println(o.getAge());
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  } catch (NoSuchFieldException e) {
   e.printStackTrace();
  }catch (IllegalAccessException | InstantiationException e){
  }
 }
}

運行結(jié)果:68

可以看出直接初始化private final Integer age變量后,不像基本類型和String類型一樣不能修改,原因是什么呢,看下class文件。

public class ReflectionUsage {
 private final Integer age = Integer.valueOf(18);
 public ReflectionUsage() {
 }
 public Integer getAge() {
  return this.age;
 }
}

可以看到編譯器并未將getAge中變量替換成常量。

看到對Integer賦值時,編譯器進行了自動裝箱,那如果初始化String變量時,使用String.value()方式時,能否被修改呢,來看一下。

/**
 * @author Cool-Coding 2018/5/15
 */
public class ReflectionUsage {
 private final String reflectionString = String.valueOf("reflectionString");
 public ReflectionUsage() {
 }
 public String getReflectionString() {
  return this.reflectionString;
 }
}

運行結(jié)果:newReflectionString

可以看出,reflectionString的值被修改了,看下class文件:

package practise.practise;
public class ReflectionUsage {
 private final String reflectionString = String.valueOf("reflectionString");
 public ReflectionUsage() {
 }
 public String getReflectionString() {
  return this.reflectionString;
 }
}

可見編譯器并未替換getReflectionString方法中的變量。

如果在構(gòu)造函數(shù)中初始化Integer類型變量呢?

public class ReflectionUsage {
 private final Integer age;
 public ReflectionUsage() {
  this.age=18;
 }
 public Integer getAge() {
  return this.age;
 }
}

運行結(jié)果:68

age值也被改變了,看下class文件:

public class ReflectionUsage {
 private final Integer age = Integer.valueOf(18);
 public ReflectionUsage() {
 }
 public Integer getAge() {
  return this.age;
 }
}

生成的class文件與直接初始化是一樣的。

總結(jié):

final可以修改類,變量,方法,表示不可繼承,不可修改,不可覆蓋(override),這里討論了使用反射修改private final修飾的成員變量情況,當(dāng)private final修改直接初始化的基本類型或String(注意不能使用String.valueOf()初始化)時,使用反射無法修改變量值,其它情況下可以修改。這也告訴我們在平時開發(fā)時,如果想定義常量請在基本類型int或String類型前加private final修飾,這樣編譯器會在編譯時將這些變量出現(xiàn)的地方替換成常量,以免被惡意修改。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 淺析Java中Apache BeanUtils和Spring BeanUtils的用法

    淺析Java中Apache BeanUtils和Spring BeanUtils的用法

    這篇文章主要介紹了Java中Apache BeanUtils和Spring BeanUtils的用法,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • Java之MyBatis入門詳解

    Java之MyBatis入門詳解

    這篇文章主要介紹了Java之MyBatis入門詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Spring?異步接口返回結(jié)果的四種方式

    Spring?異步接口返回結(jié)果的四種方式

    這篇文章主要介紹了Spring?異步接口返回結(jié)果的四種方式,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下
    2022-08-08
  • 有關(guān)IntelliJ IDEA中LeetCode插件配置問題

    有關(guān)IntelliJ IDEA中LeetCode插件配置問題

    這篇文章主要介紹了關(guān)于IntelliJ IDEA中LeetCode插件配置問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • Java陷阱之a(chǎn)ssert關(guān)鍵字詳解

    Java陷阱之a(chǎn)ssert關(guān)鍵字詳解

    這篇文章詳細(xì)介紹了Java陷阱之a(chǎn)ssert關(guān)鍵字,有需要的朋友可以參考一下
    2013-09-09
  • Java Swing組件布局管理器之FlowLayout(流式布局)入門教程

    Java Swing組件布局管理器之FlowLayout(流式布局)入門教程

    這篇文章主要介紹了Java Swing組件布局管理器之FlowLayout(流式布局),結(jié)合實例形式分析了Swing組件布局管理器FlowLayout流式布局的常用方法及相關(guān)使用技巧,需要的朋友可以參考下
    2017-11-11
  • Java后綴數(shù)組之求sa數(shù)組的實例代碼

    Java后綴數(shù)組之求sa數(shù)組的實例代碼

    后綴數(shù)組就是一個字符串所有后綴大小排序后的一個集合,然后我們根據(jù)后綴數(shù)組的一些性質(zhì)就可以實現(xiàn)各種需求。這篇文章主要介紹了Java后綴數(shù)組-求sa數(shù)組,需要的朋友可以參考下
    2018-04-04
  • Java中的Runnable,Callable,F(xiàn)uture,F(xiàn)utureTask的比較

    Java中的Runnable,Callable,F(xiàn)uture,F(xiàn)utureTask的比較

    這篇文章主要介紹了Java中的Runnable,Callable,F(xiàn)uture,F(xiàn)utureTask的比較的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • Spring事務(wù)aftercommit原理及實踐

    Spring事務(wù)aftercommit原理及實踐

    這篇文章主要為大家介紹了Spring事務(wù)aftercommit原理及實踐,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • 一文徹底掌握RocketMQ 的存儲模型

    一文徹底掌握RocketMQ 的存儲模型

    這篇文章主要介紹了RocketMQ 的存儲模型,本文的重點在于分析 BrokerServer 的消息存儲模型,筆者按照自己的理解 , 嘗試分析 RocketMQ 的存儲模型,需要的朋友可以參考下
    2022-12-12

最新評論

崇州市| 海阳市| 安龙县| 施甸县| 寿光市| 临泽县| 远安县| 乌海市| 诏安县| 新化县| 曲松县| 汽车| 稷山县| 荆州市| 卢龙县| 丽水市| 马鞍山市| 鹤山市| 那坡县| 平山县| 新营市| 通化市| 临汾市| 肃南| 西安市| 泗洪县| 本溪| 临西县| 安龙县| 兴宁市| 万源市| 怀远县| 胶南市| 武穴市| 富蕴县| 贵南县| 沙湾县| 莱西市| 彰化市| 龙岩市| 循化|