如何在java中实现对象级私有访问

时间:2013-08-05 15:58:36

标签: java encapsulation

如何将成员字段设为私有到此特定对象? 即此对象可以读取和修改该值,但同一类的其他对象不能。

e.g。

class Person 
{
    // don't mind sharing these with other persons :
    private integer houseNumber;
    private integer telephoneNumber;

    // would like this to be *really private*
    // (only visible / modifiable to this instance)
    private integer bankBalance;


    // Lots of code for interaction with other persons:
    // (e.g. maintained by co-workers)

    void interact1(Person person)
    {
        //Lots of code
    }

    void interact2(Person person)
    {
        //Lots of code
    }

    //...

    void interactN(Person person)
    {
        //Lots of code
    }
}

我知道Java的“私有”访问意味着访问仅限于此类中的代码。 从概念上讲,班级中的所有代码都在我的控制之下,所以我对此负责。控制Person对象对其他Person对象的作用应该是我的责任。

但是说我有很多方法与其他人交互,我希望编译器为我做检查,而不是亲自搜索代码。也许这个java文件与同事共享,并经常更改。

我的问题是 - 如何在Java中实现'private to this object'访问?是否有理智/明智的方法来实现它?

编辑 - 重新强调目标

我想要几行类设计/代码,以保证其他Person对象无法读/写属于此实例的bankBalance。我知道它并不是真正用Java设计的 - 但这是我动机的一部分,看看一般来说实现它的最简洁方法是什么。我真的希望编译器强制执行它 - 我不是在寻找一个涉及审计所有函数的解决方案,确保它们只调用正确的getter / access方法。

5 个答案:

答案 0 :(得分:5)

假设您的目的是防止事故而不是恶意,您可以创建一个单独的BankBalance类来跟踪谁拥有余额:

class BankBalance {
    private int bal;
    private Person belongsTo;
    public BankBalance (int initialBalance, Person belongsTo) {
        this.bal = initialBalance; this.belongsTo = belongsTo; 
    }
    public int getBalance (Person calledBy) {
        if (calledBy != belongsTo) throw new RuntimeException ("no peeking");
        return bal;
    }
}

class Person {
    private BankBalance bal;

    void checkBalance () {
        if (bal.getBalance(this) > 1000) ...
    }
}

使用getBalance时,调用者需要传递this。我认为这可能会让意外地编写代码来访问另一个人的余额变得更加困难。您还可以将BankBalance设置为嵌套类,并检查calledBy != Person.this而不是需要明确的belongsTo字段,但这样interact1可以引用person2.bal.bal(使{{1} BankBalance中的private仍然不会阻止封闭类访问它)。也许这仍然足以防止事故发生。

答案 1 :(得分:1)

正如大家所指出的,没有真正的方法可以做到这一点。你可以做一些像表格的吸气剂

private int getBankBalance(Object caller) {
     if (caller == this) {
          return bankBalance;
     } else {
          throw new RuntimeException("GTFO");
     }
}

然后强制通过object.getBankBalance(this)完成所有访问。

但是,这并不能阻止人们直接访问bankBalance或致电object.getBankBalance(object)

答案 2 :(得分:0)

您可以声明包含每个人余额的余额的arraylist。 像这样:

static int instances = 0;
private int thisInstance = 0; 
private List<Integer> balances = new Arraylist<>();

public Person() {
   instances++;
   thisInstance = instances;
   balances.add(thisInstance, new Integer(0));
}

然后,只要您拥有与bankBalance交互的代码,就只需返回与调用它的实例相同的元素。

例如,如果第五个实例试图获得它的平衡,则该方法将返回数组中的第五个余额。

例如:

private int getBankBalance() {
   return balances.get(thisInstance).intValue();
}

这样就可以让所有试图获得银行余额的人只返还余额,并且看不到任何人的余额。

答案 3 :(得分:0)

我不相信你所采取的方向是正确的,如果我是你,我会尝试从不同的角度看问题,这是你要问的一个奇怪的要求。

如果您需要的是禁止从其他对象访问属性,则无法实现此目的。如果为它指定一个getter并使用它来引用该属性,则可以这样做。

实例由其属性标识,因此您可以编写一个方法来检查某些属性,然后使用它来确定某个对象是否可以访问该属性访问器。

总而言之,它会是这样的:

private boolean isBankBalanceAccessible() {
    // check that properties are those you want,
    // for example only when houseNumber is 1234567890
    return houseNumber == 1234567890;
}

private int getBankBalance() {
    if (isBankBalanceAccessible()) {
        return bankBalance;
    } else {
        // maybe throw here?
    }
}

答案 4 :(得分:0)

我想到了这个......

     void interact1(Person person)
      {
         if(this==person)
          {
             person.bankBalance
             // Do here with the balance of the objecct which calls this function
          }


          //rest code here
      }

希望它有效.. !!