为什么这个方法必须是静态的(Java)?

时间:2016-08-11 17:41:50

标签: java static

对于某些背景,我目前在我的书中的第8章,我们完成了关于arraylists,数组,if语句,循环等的讨论。现在本书的这一部分讨论了通过引用,值和其他一些相当整洁的调用起初我觉得奇怪的事情。我读过What situation to use static和其他一些SO问题,并且学到了很多东西。

考虑我的书给出的以下示例(在许多示例中)

  

有时需要静态方法的另一个原因。如果   一个方法操纵一个你不拥有的类,你不能将它添加到   那个班。考虑一种计算矩形区域的方法。   标准库中的Rectangle类没有这样的功能,并且   我们不能修改那个类。静态方法解决了这个问题:

public class Geometry
{
  public static double area(Rectangle rect)
  {
    return rect.getWidth() * rect.getHeight();
  }
// More geometry methods can be added here.
}
  

现在我们可以告诉你为什么main方法是静态的。当程序   开始,没有任何对象。因此,第一种方法   程序必须是静态方法。

好的,这很酷,到目前为止我只是盲目地将public置于我的所有方法面前,所以很高兴知道。但下一页的评论小问题引起了我的注意

  

以下方法计算数组数组的平均值:

public static double average(ArrayList<Double> values)
  

为什么必须是静态方法?

我在这里等一下。我很确定我之前没有使用过静态。所以我尝试再次这样做,很容易想出以下

import java.util.ArrayList;
class ArrList
{
    private double sum;

    public ArrList()
    {
        sum = 0;
    }

    public double average(ArrayList <Double> values)
    {
        for(int i = 0; i < values.size() ; i++)
        {
            sum+=values.get(i);
        }

        return sum / values.size();

    }
}

public class Average
{
    public static void main(String [] args)
    {
        ArrList arrListObj = new ArrList();
        ArrayList<Double> testArrList = new ArrayList<Double>();
        testArrList.add(10.0);
        testArrList.add(50.0);
        testArrList.add(20.0);
        testArrList.add(20.0);
        System.out.println(arrListObj.average(testArrList));

    }
}

TLDR

为什么我的书说public static double average(ArrayList<Double> values)需要是静态的?

尝试使用STATIC

public class Average
{
    public static void main(String [] args)
    {
        ArrayList<Double> testArrList = new ArrayList<Double>();
        ArrayList<Double> testArrListTwo = new ArrayList<Double>();
        testArrList.add(10.0);
        testArrList.add(50.0);
        testArrList.add(20.0);
        testArrList.add(20.0);
        testArrListTwo.add(20.0);
        testArrListTwo.add(20.0);
        testArrListTwo.add(20.0);
        System.out.println(ArrList.average(testArrList));
        System.out.println(ArrList.average(testArrListTwo)); // we don't get 20, we get 53.3333!


    }
}

3 个答案:

答案 0 :(得分:1)

  1. 如果不是static,那么任何想要使用此方法的其他类必须首先创建此对象的实例。
  2. 来自其他一些课程:

    Average.average(new ArrayList<Double>()); // legal only if static
    new Average().average(new ArrayList<Double>()); // necessary if not static
    // and only makes sense if Average can be instantiated in the first place
    
    1. legal 使其成为一个实例(即非静态)变量,但该方法实际上难以理解。如果它是static那么无论谁读取代码都知道它不使用该类的任何成员变量。

      // In the class body
      int x = 0; // member variable
      public static double average() {
          x = x + 1; // illegal
      }
      
    2. 可以做的事情越少,就越容易理解所做的事情。

答案 1 :(得分:1)

它没有。

需要成为static的唯一方法是初始main()方法。任何事情和其他一切都由程序员来决定你的设计中有什么意义。

staticpublic访问器无关(正如您所提到的),它与正在执行的技术操作无关。它与操作的语义和持有它的类有关。

实例(非static)方法存在于类的特定实例上。从语义上讲,它应该执行与该特定实例相关的操作。一般来说,static方法存在于类中,并且更具概念性。它对特定实例没有任何作用(除非它提供了某个事物的实例作为方法参数)。

所以你真的需要问问自己这个操作的语义。您是否需要对象的new 实例来执行操作?或者,如果没有实例,操作是否可用?这取决于操作,对象代表什么等等。

答案 2 :(得分:1)

areaaverage等静态方法通常是实用功能。您不需要任何对象来使用实用程序功能。例如,考虑Math.pow您不需要实例化任何对象以使用幂函数,只需使用Math.pow(10.0, 2.0)来获取(10.0)^2

简而言之: 静态方法是指类方法,即不需要调用该对象的实例。 而你的average方法是一个实例方法,你需要一个对象来调用该方法。