简体   繁体   English

防止在不使用Java中的getter和setter的情况下从子类访问受保护的变量

[英]prevent protected variable access from child class without using getter and setter in java

Without using getter and setter method how to prevent modification access from child class if super class has protected Hashmap variable? 如果超类已保护Hashmap变量,则不使用getter和setter方法如何防止子类进行修改访问?

This Map is mutable (So i should be able to add the values from super class)So can't use UnmodifiableMap(its only applicable immutable collection object) 此Map是可变的(因此我应该能够从超类中添加值)因此不能使用UnmodifiableMap(其唯一适用的不可变集合对象)

    Class A
    {
      protected Map<Integer,Integer> m = new HashMap<Integer,Integer>();
      A()
       {
         m.put(10,11)
         m.put(11.12)
       }

      }

    Class B extends A
    {
      B()
      {
        super.m.put(34,90)    —— I don’t want to give access to child       class to add 

the value and child class and its only should able to get the values. 值和子类及其唯一应该能够获取值的对象。 } } }}

Make the map unmodifiable, and populate it in the construction of A. 使地图不可修改,并在A的构造中填充它。

class A {
    protected final Map<Integer,Integer> m;

    A() {
        Map<Integer, Integer> tempMap =  = new HashMap<>();
        tempMap.put(10,11);
        tempMap.put(11.12);
        this.m = java.util.Collections.unmodifiableMap(tempMap);
    }
}

If and when B attempts to modify the map, a ´UnsupportedOperationException´ will be thrown. 如果且当B尝试修改地图时,将引发“ UnsupportedOperationException”。

If you want A to be able to modify the map, then you'll need a different approach in which the map is private, and a protected getter returns an unmodifiable map. 如果您希望A能够修改地图,则需要使用另一种方法,其中地图是私有的,并且受保护的getter返回无法修改的地图。

class A {
    private final Map<Integer,Integer> m = new HashMap<>();

    A() {
        m.put(10,11);
        m.put(11.12);
        // m remains modifiable within the context of A
    }

    protected Map<Integer, Integer> getMap() {
        return java.util.Collections.unmodifiableMap(m);
    }
}

EDIT 编辑

If you really don't want to use a getter but still have read-only access, you can use this approach. 如果您确实不想使用吸气剂但仍具有只读访问权限,则可以使用此方法。

class A {
    private final Map<Integer,Integer> writableMap = new HashMap<>();
    protected final Map<Integer,Integer> m = Collections.unmodifiableMap(writableMap);

    A() {
        writableMap.put(10,11);
        writableMap.put(11.12);
    }
}

Using this approach, only m is visible outside A, and is read-only. 使用这种方法,只有m在A外可见,并且是只读的。 Within A, you can update writableMap and these changes will be visible in m 在A中,您可以更新writableMap并且这些更改将在m可见

Here is a variant of what Steve Chaloner presented in his answer: 这是Steve Chaloner在回答中提出的一种变体:

public class A {

    private final Map<Integer, Integer> map = new HashMap<>();
    protected final Map<Integer,Integer> m = Collections.unmodifiableMap(map);

    public A() {
        map.put(10, 11);
        map.put(11, 12);
    }
}

The private map is modifiable in the A class and changes will be reflected in the protected m whenever changes are made in map . 私有map可以在A类中进行修改,只要对map更改,更改就会反映在受保护的m中。


It is being used this way in Concurrency In Practice for example. 例如,在“ 并发实践”中以这种方式使用它。

This should be the best solution Composition : 这应该是最好的解决方案组成

Implement a new Map and keep an internal private modifiable map like this: 实施一个新Map并保留一个内部私有可修改地图,如下所示:

class A {

    private Map<Integer,Integer> m = new HashMap<>();

    protected Map<Integer, Integer> map = new Map<>() {
        //implement interface
        public Integer put(Integer key, Integer value) {
            throw new UnsupportedOperationException();
        }

        public Integer get(Object key) {
            return m.get(key);
        }

        public void clear() {
            throw new UnsupportedOperationException();
        }

        public boolean containsKey(Object key) {
            return m.containsKey(key);
        }

        public boolean containsValue(Object value) {
            return m.containsValue(value);
        }

        //
        // ... And so on
        //
        // ... with all other methods
    }

    A() {
        m.put(10,11)
        m.put(11.12)
    }


}

class B extends A {
    B() {
       super.map.put(34,90) // thorws exception
       super.m.put(34,90) // inaccesible
    }
}

All modifications are allowed in A via m but subclasses may only acces them by map that was succesfully blocked modifications. Am中允许所有修改,但是子类只能通过成功阻止修改的map来访问它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM