首页 > 其他分享 >get()和set()方法在保护类安全性上的意义

get()和set()方法在保护类安全性上的意义

时间:2023-05-05 09:58:33浏览次数:48  
标签:upper lower set get int public Range 安全性

1、起因

如果为一个private变量设置了get()和set()方法,不就是相当于其为public变量吗?这样做是不是过于繁琐了?

如果对形如下方的简单代码而言,可以说是上面的疑惑是对的

public class SimpleGetAndSet {
    private int n;

    public SimpleGetAndSet(int n) {
        this.n = n;
    }

    public int getN() {
        return n;
    }

    public void setN(int n) {
        this.n = n;
    }
}

2、意义

然而既然Java有这样的规范,必有其存在的意义。

2.1、类安全性


从类安全角度出发,考虑以下场景,我们需要维持一个范围对象Range,其应该满足成员变量lower小于等于upper恒成立,这样才是一个合法的范围。

倘若直接将Range类如下定义,不难发现会有以下问题:如果用户没有按照规则设置lowwer与upper,那么将会导致出现错误的范围

public class Range {
    public int lower;
    public int upper;

    public Range() {
    }
}

这样的问题对于无论是sdk或是框架或是产品等是不可接受的,我们不能保证用户一定会合法地使用Range类,不合法的使用有可能对类的安全性乃至系统的安全性造成威胁。

我们可以这样来完善:(重点关注set方法)

public class SafeRange {
    private int lower;
    private int upper;

    public SafeRange(int lower,int upper) {
        if (lower > upper) {
            try {
                throw new Exception("Lower is larger than upper");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        this.lower=lower;
        this.upper=upper;
    }

    public int getLower() {
        return lower;
    }

    public void setLower(int lower) {
        if (lower > upper) {
            try {
                throw new Exception("Lower is larger than upper");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        this.lower = lower;
    }

    public int getUpper() {
        return upper;
    }

    public void setUpper(int upper) {
        if (upper < lower) {
            try {
                throw new Exception("Upper is larger than lower");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        this.upper = upper;
    }
}

在两个set方法中,我们检查了upper和lower的合法性,这样一来在用户使用时,构造出的SafeRange一定满足lower<=upper。

顺带一提,这里的安全性没有涉及到多线程环境下的安全性,如果在多线程环境下,应该再加上synchronize关键字。

2.2、解耦


如果我们是内部人员使用,并且都知晓lower<=upper的规则,在使用Range类时会加上检查语句,那么是不是就可以任然采用原Range类的设计呢?

显然是不能的,考虑以下情况:

某一天,Range类的约束变为了lower<upper(少了等号),那么如果采用原来Range类的设计,我们需要在所有使用到它的地方改变检查语句!这显然是不可行的,会带来巨大的工作量并且不难以确保所有使用到的地方都被修改。

而倘若使用SafeRange类,我们只需要在其set()方法上稍作修改即可。

显然,set()方法在这里提供了解耦的效果

标签:upper,lower,set,get,int,public,Range,安全性
From: https://www.cnblogs.com/sxhxh/p/17373208.html

相关文章

  • 批处理中setlocal enabledelayedexpansion 变量延迟(转)
    本质上是因为批处理读取命令时是按行读取的(另外例如for命令等,其后用一对圆括号闭合的所有语句也当作一行)在一行中即使是使用变量赋值也是无作用的,使用才有了变量延迟https://www.jb51.net/article/29323.htm ......
  • MFC-CListCtrl-LVM_GETITEMTEXT获取项信息
     LVITEMlvi;TCHARch[256];lvi.pszText=ch;lvi.cchTextMax=256;lvi.mask=LVIF_TEXT;::SendMessage(hWnd4,LVM_GETITEMTEXT,(WPARAM)0,(LPARAM)&lvi);//获取项信息/*参数3:WPARAM列表视图项的索引参数4:LPARAM指向LVIT......
  • 5月4日:unordermap/set,哈希以及哈希常用的拉链法,开放地址法,以及模板的特化相关应用
    起处较为流行的数据储存方式为树形结构,再加上红黑树等优秀数据结构的发展,直到今天二叉平衡搜索树也经常被应用在各种方面,但是c++库里面还有两个与map/set很像的容器unorderedmap,他们的调用与普通的map几乎一样,有着非常优秀的查找时间复杂度,只是不能像二叉树哪样层序遍历得到顺序的......
  • Identity – user login, forgot & reset password, 2fa, external login, logout 实
    前言之前写过一篇 Identity–UserLogin,ForgotPassword,ResetPassword,Logout,当时写的比较简陋,今天有机会就写多一篇实战版.建议先阅读之前那篇做一个warmup.本篇会讲到1.userlogin2.forgotandresetpassword3.twofactor4.logout5.externallogin......
  • 探究Spring中Bean的线程安全性问题
    前言  今天同事笑嘻嘻的凑过来,问了我一个问题:spring中的bean是线程安全的吗?。我内心一想肯定是安全的,毕竟这样多项目在用。但是转念一想,他那贱兮兮的表情,多半是在给我挖坑。于是我自信的回答他:不安全。他反问,你确定......
  • 兼容 windows 和 Linux 的fgets文件读取方式(判断文件尾)
    /*检测文件尾范例使用fgets读取文件*//*范例:检测文件尾,windows和linux,unix平台兼容版本*/#include<stdio.h>#include<stdlib.h>#defineBUFSIZE100intmain(void){FILE*f;charstr[BUFSIZE];char*result;//读方式打开文件hello.txt,如果文件不......
  • wget 的断点续传功能
    使用-c选项:-c--continueContinuegettingapartially-downloadedfile.ThisisusefulwhenyouwanttofinishupadownloadstartedbyapreviousinstanceofWget,orbyanotherprogram.Forinstance:......
  • MFC-CListCtrl-GetSelectedCount获取被选中项目的总数
     UINTn=mylist4.GetSelectedCount();//获取被选中项目的总数str.Format(_T("n=%d\r\n"),n);OutputDebugString(str);    ......
  • MFC-CListCtrl-GetColumn获取列中某项信息
     LVCOLUMNlvcol;TCHARstr[256];lvcol.mask=LVCF_TEXT;lvcol.pszText=str;lvcol.cchTextMax=256;BOOLb7=mylist4.GetColumn(1,&lvcol);//获取列中某项信息//参数1:列号//【不设置iSubItem,就是列头信息;设置......
  • k8s 控制器-Replicaset-Deployment cordon drain
    k8s控制器-Replicaset-Deployment#cordon警戒线 执行后不会在调度到该节点上了[root@master01deployment]#kubectlcordonnode01node/node01cordoned[root@master01deployment]# NAMESTATUSROLESAGEVERSIONmaster0......