为啥允许静态方法调用私有方法?

Posted

技术标签:

【中文标题】为啥允许静态方法调用私有方法?【英文标题】:Why static methods are allowed to invoke private methods?为什么允许静态方法调用私有方法? 【发布时间】:2013-11-12 08:26:12 【问题描述】:

我以前从未尝试过编写以下代码,因为它在生产中没有多大意义。但令我惊讶的是,这段代码编译成功。 为什么它被设计成允许从同一类的实例上的静态方法调用私有方法?

public class Beverage 
    private void drink () 
        System.out.println("Beverage");
    

    public static void main (String[] args)     
        Beverage b = new Beverage();
        b.drink(); //call to private method!
    

【问题讨论】:

【参考方案1】:

您可以通过拥有包含非静态方法的类的实例从静态方法访问非静态方法。所以这里

    你可以调用非静态方法,因为你有一个实例

    您可以将私有方法作为同一个类中的两种方法调用。

【讨论】:

【参考方案2】:

您注意到的行为是最符合private 定义的行为。

在 Java 中,private 表示“只能从同一个类中调用”。这并不意味着“只能被拥有的对象调用”。我怀疑这是 Java 起源的保留,因为与 C++ 的相似性而做出了很多决定,C++ 的定义与 private 相同。

它还允许你做一些事情,比如拥有一个只有 private 构造函数的类,以及用于实例化类的 static 方法。

【讨论】:

【参考方案3】:

访问级别修饰符确定其他类是否可以使用特定字段或调用特定方法。 private 访问说明符限制了类外部的可见性,但它允许方法/字段在类内部可见和可用。

【讨论】:

【参考方案4】:

静态成员是类成员,非静态成员是实例成员。在这里,您使用了一个实例来调用一个完全没问题的实例方法。但你不能像下面这样调用。

public class Beverage 
    private void drink () 
        System.out.println("Beverage");
    

    public static void main (String[] args)     

        drink(); //call to private method!this is wrong no matter private or public
    

【讨论】:

【参考方案5】:

为什么他们不能打电话给他们? private 限制对同一类的访问。静态方法在同一个类中。所以它可以访问私有方法。

访问修饰符在类级别起作用,而不是在实例级别。如果它们在实例级别工作,您无法编写静态工厂方法(调用私有构造函数和初始化方法)、equals() 方法和compareTo 方法(比较两个实例的私有字段)等。

【讨论】:

关于静态工厂方法的要点!完全忘记了。

以上是关于为啥允许静态方法调用私有方法?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 C# 不允许静态方法实现接口?

java中私有的属性、静态成员可以被子类继承吗?

对象的私有/公有/静态/特权 属性/方法

为啥在 Eloquent 模型中调用方法时出现“不应静态调用非静态方法”?

为啥可以从对象范围之外调用私有方法?

java调用同一个类中的方法为啥要将方法申明成静态?