为什么要在Java中公开私有内部类成员?

时间:2023-01-15 15:36:01

What is the reason of declaring a member of a private inner class public in Java if it still can't be accessed outside of containing class? Or can it?

如果在包含类之外仍然无法访问Java中私有内部类公共成员的原因是什么?或者可以吗?

public class DataStructure {
    // ...

    private class InnerEvenIterator {
        // ...

        public boolean hasNext() { // Why public?
            // ...
        }
    }
}

6 个解决方案

#1


30  

If the InnerEvenIterator class does not extend any class or implement any interface, I think it is nonsense because no other class can access any instance of it.

如果InnerEvenIterator类没有扩展任何类或实现任何接口,我认为这是无稽之谈,因为没有其他类可以访问它的任何实例。

However, if it extends or implements any other non private class or interface, it makes sense. An example:

但是,如果它扩展或实现任何其他非私有类或接口,它是有道理的。一个例子:

interface EvenIterator {
    public boolean hasNext();
}


public class DataStructure {
    // ...

    private class InnerEvenIterator implements EvenIterator{
        // ...

        public boolean hasNext() { // Why public?
            // ...
        }
    }

    InnerEvenIterator iterator;

    public EvenIterator getIterator(){
         return iterator;
    }     

}

#2


13  

This method can be made public in order to indicate that it's semantically public, despite the fact that compiler doesn't enforce visibility rules in this particular case.

尽管编译器在这种特定情况下不强制执行可见性规则,但是可以将此方法公开以表明它在语义上是公共的。

Imagine that during some refactoring you need to make this inner class top-level. If this method is private, how would you decide whether it should be made public, or some more restrictive modifier should be used? Declaring method as public tells reader the intentions of original author - this method shouldn't be considered an implementation detail.

想象一下,在一些重构过程中,你需要让这个内部类成为*。如果此方法是私有的,您将如何决定是否应该公开,还是应该使用一些更严格的修饰符?公开声明方法告诉读者原作者的意图 - 这种方法不应被视为实现细节。

#3


8  

It is useful when you implement any interface.

实现任何接口时都很有用。

class DataStructure implements Iterable<DataStructure> {

    @Override
    public Iterator<DataStructure> iterator() {
        return new InnerEvenIterator();
    }
    // ...        

    private class InnerEvenIterator implements Iterator<DataStructure> {
        // ...    
        public boolean hasNext() { // Why public?
            // ...
            return false;
        }

        @Override
        public DataStructure next() {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }

    public static void main(String[] ex) {
        DataStructure ds = new DataStructure();
        Iterator<DataStructure> ids = ds.iterator();
        ids.hasNext(); // accessable            
    }
}

#4


4  

I think you are missing the implementing the Iterator interface part in your sample code. In that case, you can't make the hasNext() method have any other visibility identifier other than public since that would end up reducing its visibility (interface methods have public visibility) and it won't compile.

我认为您缺少在示例代码中实现Iterator接口部分。在这种情况下,您不能使hasNext()方法具有除public之外的任何其他可见性标识符,因为这最终会降低其可见性(接口方法具有公共可见性)并且它将无法编译。

#5


3  

There are many combinations of access modifiers which are not useful. A public method in a private inner class is only useful if it implements a public method in a public class/interface.

存在许多无用的访问修饰符组合。私有内部类中的公共方法仅在公共类/接口中实现公共方法时才有用。

public class DataStructure {
    // ...

    private class InnerEvenIterator implements Iterator {
        // ...

        public boolean hasNext() { // Why public?
            // ...
        }
    }

    public Iterator iterator() {
        return new InnerEvenIterator();
    }
}

BTW: abstract classes often have public constructors when actually they are protected

顺便说一句:抽象类通常具有公共构造函数,实际上它们受到保护

#6


1  

If the inner class is private it cannot be accessed by name outside of the outer class. Inner and outer classes have access to each other's private methods and private instance variables. As long as you are within the inner or outer class, the modifiers public and private have the same effect. In your code example:

如果内部类是私有的,则不能通过外部类之外的名称来访问它。内部类和外部类可以访问彼此的私有方法和私有实例变量。只要您在内部或外部类中,公共和私有修饰符具有相同的效果。在您的代码示例中:

public class DataStructure {
    // ...

    private class InnerEvenIterator {
        // ...

        public boolean hasNext() { // Why public?
            // ...
        }
    }
}

As far as the class DataStructure is concerned, this is completely equivalent to:

就类DataStructure而言,这完全等同于:

public class DataStructure {
    // ...

    private class InnerEvenIterator {
        // ...

        private boolean hasNext() {
            // ...
        }
    }
}

This is because only DataStructure can access it, so it doesn't matter if you set it to public or private. Either way, DataStructure is still the only class that can access it. Use whichever modifier you like, it makes no functional difference. The only time you can't choose at random is when you are implementing or extending, in which case you can't reduce the access, but you can increase it. So if an abstract method has protected access you can change it to public. Granted neither one actually makes any difference.

这是因为只有DataStructure可以访问它,因此如果将其设置为public或private则无关紧要。无论哪种方式,DataStructure仍然是唯一可以访问它的类。使用你喜欢的任何修改器,它没有任何功能差异。您无法随意选择的唯一时间是您实施或扩展时,在这种情况下您无法减少访问权限,但您可以增加它。因此,如果抽象方法具有受保护的访问权限,则可以将其更改为public。当然,没有人真正有任何区别。

If you plan on using an inner class in other classes, and therefore making it public, you probably shouldn't make it an inner class in the first place.

如果您计划在其他类中使用内部类,并因此将其公开,那么您可能不应该首先将其作为内部类。

Additionally, I don't see any requirement for inner classes extending or implementing other classes. It might be common for them to do so, but it's certainly not required.

另外,我没有看到内部类扩展或实现其他类的任何要求。他们这样做可能很常见,但肯定不是必需的。

#1


30  

If the InnerEvenIterator class does not extend any class or implement any interface, I think it is nonsense because no other class can access any instance of it.

如果InnerEvenIterator类没有扩展任何类或实现任何接口,我认为这是无稽之谈,因为没有其他类可以访问它的任何实例。

However, if it extends or implements any other non private class or interface, it makes sense. An example:

但是,如果它扩展或实现任何其他非私有类或接口,它是有道理的。一个例子:

interface EvenIterator {
    public boolean hasNext();
}


public class DataStructure {
    // ...

    private class InnerEvenIterator implements EvenIterator{
        // ...

        public boolean hasNext() { // Why public?
            // ...
        }
    }

    InnerEvenIterator iterator;

    public EvenIterator getIterator(){
         return iterator;
    }     

}

#2


13  

This method can be made public in order to indicate that it's semantically public, despite the fact that compiler doesn't enforce visibility rules in this particular case.

尽管编译器在这种特定情况下不强制执行可见性规则,但是可以将此方法公开以表明它在语义上是公共的。

Imagine that during some refactoring you need to make this inner class top-level. If this method is private, how would you decide whether it should be made public, or some more restrictive modifier should be used? Declaring method as public tells reader the intentions of original author - this method shouldn't be considered an implementation detail.

想象一下,在一些重构过程中,你需要让这个内部类成为*。如果此方法是私有的,您将如何决定是否应该公开,还是应该使用一些更严格的修饰符?公开声明方法告诉读者原作者的意图 - 这种方法不应被视为实现细节。

#3


8  

It is useful when you implement any interface.

实现任何接口时都很有用。

class DataStructure implements Iterable<DataStructure> {

    @Override
    public Iterator<DataStructure> iterator() {
        return new InnerEvenIterator();
    }
    // ...        

    private class InnerEvenIterator implements Iterator<DataStructure> {
        // ...    
        public boolean hasNext() { // Why public?
            // ...
            return false;
        }

        @Override
        public DataStructure next() {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }

    public static void main(String[] ex) {
        DataStructure ds = new DataStructure();
        Iterator<DataStructure> ids = ds.iterator();
        ids.hasNext(); // accessable            
    }
}

#4


4  

I think you are missing the implementing the Iterator interface part in your sample code. In that case, you can't make the hasNext() method have any other visibility identifier other than public since that would end up reducing its visibility (interface methods have public visibility) and it won't compile.

我认为您缺少在示例代码中实现Iterator接口部分。在这种情况下,您不能使hasNext()方法具有除public之外的任何其他可见性标识符,因为这最终会降低其可见性(接口方法具有公共可见性)并且它将无法编译。

#5


3  

There are many combinations of access modifiers which are not useful. A public method in a private inner class is only useful if it implements a public method in a public class/interface.

存在许多无用的访问修饰符组合。私有内部类中的公共方法仅在公共类/接口中实现公共方法时才有用。

public class DataStructure {
    // ...

    private class InnerEvenIterator implements Iterator {
        // ...

        public boolean hasNext() { // Why public?
            // ...
        }
    }

    public Iterator iterator() {
        return new InnerEvenIterator();
    }
}

BTW: abstract classes often have public constructors when actually they are protected

顺便说一句:抽象类通常具有公共构造函数,实际上它们受到保护

#6


1  

If the inner class is private it cannot be accessed by name outside of the outer class. Inner and outer classes have access to each other's private methods and private instance variables. As long as you are within the inner or outer class, the modifiers public and private have the same effect. In your code example:

如果内部类是私有的,则不能通过外部类之外的名称来访问它。内部类和外部类可以访问彼此的私有方法和私有实例变量。只要您在内部或外部类中,公共和私有修饰符具有相同的效果。在您的代码示例中:

public class DataStructure {
    // ...

    private class InnerEvenIterator {
        // ...

        public boolean hasNext() { // Why public?
            // ...
        }
    }
}

As far as the class DataStructure is concerned, this is completely equivalent to:

就类DataStructure而言,这完全等同于:

public class DataStructure {
    // ...

    private class InnerEvenIterator {
        // ...

        private boolean hasNext() {
            // ...
        }
    }
}

This is because only DataStructure can access it, so it doesn't matter if you set it to public or private. Either way, DataStructure is still the only class that can access it. Use whichever modifier you like, it makes no functional difference. The only time you can't choose at random is when you are implementing or extending, in which case you can't reduce the access, but you can increase it. So if an abstract method has protected access you can change it to public. Granted neither one actually makes any difference.

这是因为只有DataStructure可以访问它,因此如果将其设置为public或private则无关紧要。无论哪种方式,DataStructure仍然是唯一可以访问它的类。使用你喜欢的任何修改器,它没有任何功能差异。您无法随意选择的唯一时间是您实施或扩展时,在这种情况下您无法减少访问权限,但您可以增加它。因此,如果抽象方法具有受保护的访问权限,则可以将其更改为public。当然,没有人真正有任何区别。

If you plan on using an inner class in other classes, and therefore making it public, you probably shouldn't make it an inner class in the first place.

如果您计划在其他类中使用内部类,并因此将其公开,那么您可能不应该首先将其作为内部类。

Additionally, I don't see any requirement for inner classes extending or implementing other classes. It might be common for them to do so, but it's certainly not required.

另外,我没有看到内部类扩展或实现其他类的任何要求。他们这样做可能很常见,但肯定不是必需的。