18

我正在浏览一段类似这样的代码

// compare points according to their polar radius
public static final Comparator<Point2D> R_ORDER = new ROrder();
.
.
.
private static class ROrder implements Comparator<Point2D> {
    public int compare(Point2D p, Point2D q) {
        double delta = (p.x*p.x + p.y*p.y) - (q.x*q.x + q.y*q.y);
        if (delta < 0) return -1;
        if (delta > 0) return +1;
        return 0;
    }
}

为什么我们在私有静态类中有这样的公共方法。如果我做了 ROrder 会有什么危害

  1. 非静态
  2. 上市
4

4 回答 4

11

ROrder非静态

通过制作它,non-static您将需要容器类的实例来创建 的实例ROder,这可能是由于该类的设计不会产生逻辑。只有当您确实需要外部类的实例来获取内部类的实例时,您才应该保持类非静态。

ROrder上市

再次因为他们想限制在ROrder这个类的上下文之外的使用。他们不希望任何客户端代码或其他代码自由创建 的实例ROrder,因为它们没有任何用处。

为什么我们在私有静态类中有这样的公共方法。

在这种情况下,因为您正在实现 aninterface Comparator并且您将传递此比较器以用于其他用途,例如排序,并且您希望Collections该类具有方法的可见性,所以即使实现接口的类是compare,该方法也必须是.publicprivate

所以这只是增强代码的可读性使用意图的一种合乎逻辑的方式。

逻辑使用

此类希望字符串采用某种格式。

public class SomeClass{

     private static class StringHelper{
          //will do the task of parsing and validating that string object
     } 
}

现在在这种情况下,您不想保留StringHelperclass public,因为它的使用过于本地化而无法重用。因此,您宁愿通过保留它来强调这一点privatepublic如果StringHelper实现了某个接口,则可能存在一些方法。

更新:

只有当您确实需要外部类的实例来获取内部类的实例时,您才应该保持类非静态。

关于这一点,我认为答案可能过于宽泛,但我会尽量简短地解释一下。我的意思是,如果内部类对象共享其处理所依赖的外部对象的某些状态,那么您将需要外部类的对象与内部类对象共享其状态,但是如果内部类instance 独立于外部类的状态,那么保持内部类是安全的static

于 2013-09-18T09:33:32.073 回答
6

此类实现Comparator,因此必须实现其方法。实现方式不能static。此外,由于接口方法是隐式的,因此无论包含类的可见性如何public,都必须声明它们。public尝试不这样做,它将无法编译。这当然是它public在这里宣布的原因——不可能没有。

无论包含类是static还是,这都是正确的public。在这里,它可能是这些东西中的任何一个,并且里面的方法仍然必须是public和非static

其他不实现接口的方法可能是private,并且逻辑上可能应该在一个private类中,否则声明它是没有意义的——但它是 Java 语法允许的。

于 2013-09-18T09:30:31.703 回答
4

所有私有成员(字段、类等)仅在类内可见。因此,您为私有类的方法提供何种可见性并不重要——所有方法都只能在包含的类中可见,因为该类本身是私有的。

如果内部类实现了一个接口或扩展了一个类,则被覆盖的方法的可见性可能不会低于超类型中的声明,因此这是在私有内部类中具有公共方法的原因之一。

然而,尽管该语法允许私有类具有公共方法,但它不会将这些方法的可见性提高到足以在包含类之外可见的程度。java中有几个修饰符合法但无效的示例,例如内部接口是隐式静态的(无论是否使用静态关键字)。

于 2013-09-18T09:28:34.153 回答
1

这个类是私有的,因为开发者不想在其他地方实例化 ROrder。但是可以通过R_ORDER其他类的常量访问实例。

该方法是公开的有两个原因:首先,compareComparator接口中定义。其次,由于 R_ORDER 可以从其他类访问,因此能够在该对象上调用方法非常方便。在这种情况下,它是compare

最后,如果类不是静态的,它会保留对父类的引用,这几乎总是不需要的

于 2013-09-18T09:32:44.757 回答