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

java安全編碼指南之:Mutability可變性詳解

 更新時(shí)間:2020年09月14日 11:35:31   作者:flydean程序那些事  
這篇文章主要介紹了java安全編碼指南之:Mutability可變性詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

簡(jiǎn)介

mutable(可變)和immutable(不可變)對(duì)象是我們?cè)趈ava程序編寫的過(guò)程中經(jīng)常會(huì)使用到的。

可變類型對(duì)象就是說(shuō),對(duì)象在創(chuàng)建之后,其內(nèi)部的數(shù)據(jù)可能會(huì)被修改。所以它的安全性沒(méi)有保證。

而不可變類型對(duì)象就是說(shuō),對(duì)象一旦創(chuàng)建之后,其內(nèi)部的數(shù)據(jù)就不能夠被修改,我們可以完全相信這個(gè)對(duì)象。

雖然mutable對(duì)象安全性不夠,但是因?yàn)槠淇梢员恍薷?,所以?huì)有效的減少對(duì)該對(duì)象的拷貝。

而immutable對(duì)象因?yàn)椴豢筛淖儯試L試對(duì)該對(duì)象的修改都會(huì)導(dǎo)致對(duì)象的拷貝,從而生成新的對(duì)象。

我們最常使用的String就是一個(gè)immutable對(duì)象。

那么可變性在java的安全編碼中的最佳實(shí)踐是怎么樣的呢? 一起來(lái)看看吧。

可變對(duì)象和不可變對(duì)象

知道了可變對(duì)象和不可變對(duì)象的不同之處之后,我們看一下怎么才能判斷這個(gè)對(duì)象是可變對(duì)象還是不可變對(duì)象呢?

首先,最簡(jiǎn)單的一點(diǎn)就是,不可變對(duì)象創(chuàng)建之后就不能夠被修改,所以不可變對(duì)象里面基本上沒(méi)有setXXX之類的方法,而可變對(duì)象提供了setXXX這些可以修改內(nèi)部變量狀態(tài)的方法。

看一個(gè)例子java.util.Date是一個(gè)可變對(duì)象,而java.time.LocalTime是不可變對(duì)象。

看下他們的方法定義有什么區(qū)別呢?

首先是Date,我們可以看到在其中定義了很多setXXX方法。

而在LocalTime中,我們基本上看不到setXXX方法。

同時(shí)不可變對(duì)象的字段基本上都是final的,防止被二次修改。

第二,不可變對(duì)象一般來(lái)說(shuō)是不可繼承的,在java中就是以final關(guān)鍵字做限定的:

public class Date

public final class LocalTime

第三,不可變對(duì)象一般會(huì)隱藏構(gòu)造函數(shù),而是使用類似工廠模式的方法來(lái)創(chuàng)建對(duì)象,這樣為實(shí)例的創(chuàng)建提供了更多的機(jī)動(dòng)性。

創(chuàng)建mutable對(duì)象的拷貝

那么如果我們想使用mutable對(duì)象,又不想被別人修改怎么辦呢?

簡(jiǎn)單的辦法就是拷貝一份要使用的對(duì)象:

public class CopyOutput {
      private final java.util.Date date;
      ...
      public java.util.Date getDate() {
        return (java.util.Date)date.clone();
      }
    }

這里大家還要注意深拷貝和淺拷貝的問(wèn)題。

為mutable類創(chuàng)建copy方法

既然要為mutable對(duì)象創(chuàng)建拷貝,那么相應(yīng)的mutable類也需要提供一個(gè)copy方法來(lái)協(xié)助拷貝。

這里需要考慮一個(gè)深拷貝和淺拷貝的問(wèn)題。

不要相信equals

我們知道在HashMap中怎么去查找一個(gè)key呢?先去找這個(gè)key的hash值,然后去判斷key.equals方法是否相等,考慮下面這種情況:

private final Map<Window,Extra> extras = new HashMap<>();

    public void op(Window window) {
      Extra extra = extras.get(window);
    }

op方法接收一個(gè)Window對(duì)象,然后將其當(dāng)成key從HashMap中取出對(duì)應(yīng)的value。

如果,這個(gè)時(shí)候,我們有一個(gè)類A繼承了Window,并且hash值和equals都和另外一個(gè)Window對(duì)象B相同,那么使用A這個(gè)key可以獲取到B這個(gè)key存儲(chǔ)的數(shù)據(jù)!

怎么解決這個(gè)問(wèn)題呢?

Java中有一個(gè)特別的HashMap:IdentityHashMap,這個(gè)Map的key和value比較是用==而不是equals方法,所以可以有效的避免上面出現(xiàn)的問(wèn)題。

private final Map<Window,Extra> extras = new IdentityHashMap<>();

    public void op(Window window) {
      Extra extra = extras.get(window);
    }

如果沒(méi)有這樣的Map可用,那么可以使用不可變對(duì)象作為key或者使用Window的私有變量,從而惡意攻擊者無(wú)法獲得這個(gè)變量。

public class Window {
      /* pp */ 
      class PrivateKey {
        Window getWindow() {
          return Window.this;
        }
      }
      final PrivateKey privateKey = new PrivateKey();

      private final Map<Window.PrivateKey,Extra> extras =
         new WeakHashMap<>();
      ...
    }

    public class WindowOps {
      public void op(Window window) {
        // Window.equals may be overridden,
        // but safe as we don't use it.
        Extra extra = extras.get(window.privateKey);
        ...
      }
    }

不要直接暴露可修改的屬性

如果一個(gè)可變類中的某個(gè)屬性確實(shí)需要暴露被外部使用,那么一定要將這個(gè)屬性定義為private,并且使用wrapper方法將其包裝起來(lái)。

如果直接暴露出去,那么基本上就沒(méi)有權(quán)限控制可言,任何程序只要能夠拿到你這個(gè)對(duì)象,就可以對(duì)屬性進(jìn)行修改。考慮下下面的應(yīng)用方式,我們?cè)谛薷膕tate的方法中加入了一個(gè)參數(shù)校驗(yàn)和權(quán)限控制。

public final class WrappedState {
      // private immutable object
      private String state;

      // wrapper method
      public String getState() {
        return state;
      }

      // wrapper method
      public void setState(final String newState) {
        this.state = requireValidation(newState);
      }

      private static String requireValidation(final String state) {
        if (...) {
          throw new IllegalArgumentException("...");
        }
        return state;
      }
    }

public static fields應(yīng)該被置位final

同樣的,如果你是一個(gè)類變量,當(dāng)然不希望這個(gè)變量會(huì)被任何人修改,那么需要將其置位final。

public class Files {
      public static final String separator = "/";
      public static final String pathSeparator = ":";
    }

public static final field 應(yīng)該是不可變的

如果類變量是public static final的,那么這個(gè)變量一定要是不可變的。

有人會(huì)問(wèn)了,都定義成了final了,是不是就已經(jīng)不可變了?

其實(shí)不然,比如我們定義了一個(gè)final的List,雖然這個(gè)list不能變化,但是list里面的值是可以變化的。我們需要將可變變量修改為不可變變量,如下所示:

import static java.util.Arrays.asList;
    import static java.util.Collections.unmodifiableList;
    ...
    public static final List<String> names = unmodifiableList(asList(
      "Fred", "Jim", "Sheila"
    ));

如果使用JDK9中引入的of()或者ofEntries()方法,可以直接創(chuàng)建不可修改的集合:

public static final List
<String> names =
 List.of("Fred", "Jim", "Sheila");

以上這篇java安全編碼指南之:Mutability可變性詳解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Maven本地倉(cāng)庫(kù)的配置以及修改默認(rèn).m2倉(cāng)庫(kù)位置

    Maven本地倉(cāng)庫(kù)的配置以及修改默認(rèn).m2倉(cāng)庫(kù)位置

    今天小編就為大家分享一篇關(guān)于Maven本地倉(cāng)庫(kù)的配置以及修改默認(rèn).m2倉(cāng)庫(kù)位置的文章,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-10-10
  • jQuery.event.trigger()的簡(jiǎn)單解釋

    jQuery.event.trigger()的簡(jiǎn)單解釋

    今天小編就為大家分享一篇關(guān)于jQuery.event.trigger()的簡(jiǎn)單解釋,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-10-10
  • 解決Weblogic部署war找不到spring配置文件的問(wèn)題

    解決Weblogic部署war找不到spring配置文件的問(wèn)題

    這篇文章主要介紹了解決Weblogic部署war找不到spring配置文件的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。
    2021-07-07
  • Java舉例講解分治算法思想

    Java舉例講解分治算法思想

    分治算法的基本思想是將一個(gè)規(guī)模為N的問(wèn)題分解為K個(gè)規(guī)模較小的子問(wèn)題,這些子問(wèn)題相互獨(dú)立且與原問(wèn)題性質(zhì)相同。求出子問(wèn)題的解,就可得到原問(wèn)題的解,本篇文章我們就用分治算法來(lái)實(shí)現(xiàn)歸并排序快速排序以及二分搜索算法
    2022-04-04
  • java中線程中斷的實(shí)現(xiàn)示例

    java中線程中斷的實(shí)現(xiàn)示例

    中斷只是一種協(xié)作協(xié)商機(jī)制,Java沒(méi)有給中斷增加任何語(yǔ)法,中斷的過(guò)程完全需要程序員自己實(shí)現(xiàn),本文就來(lái)介紹一下線程中斷的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • Java在排序數(shù)組中查找元素的第一個(gè)和最后一個(gè)位置的方法詳解

    Java在排序數(shù)組中查找元素的第一個(gè)和最后一個(gè)位置的方法詳解

    相信大家在操作Java的時(shí)候經(jīng)常會(huì)要在一個(gè)數(shù)組(無(wú)序)中查找元素的第一個(gè)和最后一個(gè)位置,下面這篇文章主要給大家介紹了關(guān)于Java在排序數(shù)組中查找元素的第一個(gè)和最后一個(gè)位置的相關(guān)資料,需要的朋友可以參考下
    2024-01-01
  • SpringBoot配置數(shù)據(jù)庫(kù)密碼加密的實(shí)現(xiàn)

    SpringBoot配置數(shù)據(jù)庫(kù)密碼加密的實(shí)現(xiàn)

    這篇文章主要介紹了SpringBoot配置數(shù)據(jù)庫(kù)密碼加密的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 淺談SpringBoot處理url中的參數(shù)的注解

    淺談SpringBoot處理url中的參數(shù)的注解

    下面小編就為大家分享一篇淺談SpringBoot處理url中的參數(shù)的注解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • Java基礎(chǔ)教程之理解Annotation詳細(xì)介紹

    Java基礎(chǔ)教程之理解Annotation詳細(xì)介紹

    這篇文章主要介紹了Java基礎(chǔ)教程之理解Annotation詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • Window搭建部署RocketMQ步驟詳解

    Window搭建部署RocketMQ步驟詳解

    這篇文章主要介紹了Window搭建部署RocketMQ步驟詳解,RocketMq是一個(gè)由阿里巴巴開源的消息中間件,脫胎去阿里每部使用的MetaQ,在設(shè)計(jì)上借鑒了Kafka。,需要的朋友可以參考下
    2019-06-06

最新評(píng)論

射洪县| 阜阳市| 静安区| 英德市| 福泉市| 辽中县| 鄯善县| 平南县| 秦安县| 惠来县| 玉环县| 青海省| 张家口市| 铜陵市| 吉木乃县| 黔江区| 怀来县| 宁远县| 邢台县| 周口市| 东阳市| 沾益县| 阳泉市| 德昌县| 滦平县| 兴安县| 浠水县| 嫩江县| 浏阳市| 芦山县| 清原| 聂拉木县| 乌兰浩特市| 绥滨县| 来宾市| 望奎县| 商城县| 斗六市| 金溪县| 韶关市| 台湾省|