静态和非静态方法/子例程之间的区别

时间:2015-12-03 05:53:47

标签: java static-methods subroutine non-static

我正在读一本java书,在那里我看到了这句话:

So, every subroutine is contained either in a class or in an object

我真的很困惑为什么会说 "class or in an object"

我想要一些解释。

4 个答案:

答案 0 :(得分:2)

试试这个例子

public class Demo {

    public static void classMethod() {
        System.out.println("Call to static method");
    }

    public void objectMethod() {
        System.out.println("Call to object method");
    }

    public static void main(String[] args) {
        Demo demo = null;
        demo.classMethod();
        //demo.objectMethod();// throws NPE if uncommented
    }
}

此代码将起作用(即使demo变量为null),因为静态方法classMethod包含在类Demo中。注释行将抛出NullPointerException,因为方法objectMethod不包含在类中但在对象中,因此需要Demo类的实例来调用它。

答案 1 :(得分:1)

子程序是在类中编写的方法。我们用它们来完成各种任务。该语句声明这些方法/子例程是在对象或类中编写的。

如果我们有一个实例化的对象,它将为该对象的每个non-static方法创建新方法,这些方法在对象的类中定义。因此,那些non-static方法/子例程在对象中。

但是如果类是static类,我们就不能有任何对象。但是我们可以使用该类的子程序/方法。所以,他们在Class

这就是你的陈述所说的。

修改

我想为此举一个例子。

public class ExampleClass {

  public String getNonStaticString() {
    return "This String is From Non-Static Method";
  }

  public static String getStaticString() {
    return "This String is From Static Method"
  }
}

然后,如果你需要获得static字符串,你所要做的就是

String staticString = ExampleClass.getStaticString();

请注意,我没有从ExampleClass这里创建一个对象。我刚用过这个方法。

但是,如果您需要从String方法获取non-static,则应首先实例化对象。

ExampleClass exampleObject = new ExampleClass();
String nonStaticString = exampleObject.getNonStaticString();

答案 2 :(得分:0)

静态方法也称为类方法。静态方法仅与类关联,而不与该类(对象)的任何特定实例关联。

答案 3 :(得分:0)

  

因此,每个子例程都包含在类或对象中

该声明在技术上并非100%正确。

首先,java中的子程序通常称为方法。以下两个术语经常互换使用:

  • 方法:使用对象实例this的子例程。
  • 功能:子程序使用对象实例。

    以下是一个示例场景,您应该知道这意味着什么:

    public class Circle {
        //region static code
        //we cannot call "this" in a static context, main(String[]) is no exception here
        public static void main(String[] args) {
            Circle a = new Circle(0, 0, 10);
            Circle b = new Circle(10, 10, 2);
            System.out.println("a                  = " + a);
            System.out.println("b                  = " + b);
            System.out.println("circumference of a = " + a.getCircumference());
            System.out.println("circumference of b = " + b.getCircumference());
            System.out.println("area of a          = " + a.getArea());
            System.out.println("area of b          = " + b.getArea());
            System.out.println("distance of a, b   = " + distance(a, b));
            System.out.println("a, b intersect     = " + (intersects(a, b) ? "yes" : "no"));
        }
    
        //we cannot call "this" in a static context, but we have the circles a, b as parameters we can use to calculate their distance
        public static double distance(Circle a, Circle b) {
            return Math.sqrt(squared(a.x - b.x) + squared(a.y - b.y));
    
        }
    
        //we cannot call "this" in a static context, but we have the circles a, b as parameters we can use to check for an intersection
        public static boolean intersects(Circle a, Circle b) {
            return a.radius + b.radius > distance(a, b);
    
        }
    
        //we cannot call "this" in a static context, but we have the number x as parameter we can use to calculate the square of
        public static double squared(double x) {
            return x * x;
    
        }
    
        //we cannot call "this" in a static context, but we have the number radius as parameter we can use to check if its value is in range
        public static void checkRadius(double radius) {
            if(radius < 0) {
                throw new IllegalArgumentException("radius must be >= 0");
            }
        }
        //endregion
    
        //region member / instance code
        private double x;
        private double y;
        private double radius;
    
        public Circle(double x, double y, double radius) {
            checkRadius(radius);
            this.x = x;
            this.y = y;
            this.radius = radius;
        }
    
        //region getters and setters
        //we may refer to the instance variables with or without "this", sometimes it is necessary to clarify - see: setX(double)
        public double getX() {
            return x;
        }
    
        //we may refer to the instance variables with or without "this", but in this case we have two variables with name "x"
        //if we write "x", the parameter is taken. for the circle's x coordinate, we need to clarify with "this.x"
        public void setX(double x) {
            this.x = x;
        }
    
        public double getY() {
            return y;
        }
    
        public void setY(double y) {
            this.y = y;
        }
    
        public double getRadius() {
            return radius;
        }
    
        public void setRadius(double radius) {
            checkRadius(radius);
            this.radius = radius;
        }
        //endregion
    
        //we may refer to the instance variables with or without "this", sometimes it is necessary to clarify - see: setX(double)
        public double getCircumference() {
            return 2 * Math.PI * radius;
        }
    
        public double getArea() {
            return Math.PI * squared(radius);
        }
    
        //we may refer to the instance variables with or without "this", sometimes it is necessary to clarify - see: setX(double)
        @Override
        public String toString() {
            return "circle at [" + x + ", " + y + "] with radius " + radius;
        }
        //endregion
    }
    

    <强>输出

    a                  = circle at [0.0, 0.0] with radius 10.0
    b                  = circle at [10.0, 10.0] with radius 2.0
    circumference of a = 62.83185307179586
    circumference of b = 12.566370614359172
    area of a          = 314.1592653589793
    area of b          = 12.566370614359172
    distance of a, b   = 14.142135623730951
    a, b intersect     = no