【问题标题】:Difference between Static and Non-Static methods/Subroutines静态和非静态方法/子程序之间的区别
【发布时间】:2015-12-03 05:53:46
【问题描述】:

我正在阅读一本 java 书,其中我遇到了这样的声明:

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

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

我想要一些解释。

【问题讨论】:

    标签: java static-methods subroutine non-static


    【解决方案1】:

    让我们试试这个例子

    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 类的实例来调用它。

    【讨论】:

    • 你真的向学习java的菜鸟展示了对实例变量的静态调用吗?
    【解决方案2】:

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

    如果我们实例化了一个对象,它将为该对象的每个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 这里创建对象。我只是用了这个方法。

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

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

    【讨论】:

    • 如果一个成员是静态的,那么在不创建对象的情况下我们如何使用这些静态成员
    • 我们可以自己调用类。
    • @SumeetChand 我认为你应该在这里接受答案。
    【解决方案3】:

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

    【讨论】:

    • 你能解释一下子程序吗?
    • 在java子程序中常被称为方法。示例:类号 { getValue();
    • 这意味着如果我在一个类中声明某些东西是静态的,那么该类的一个实例就不能访问它?
    • 在java子程序中常被称为方法。静态与非静态方法的示例:class Number { private int value; public static Number getRandomNumber() { Number n = /* 生成一些数字 */ return N } public int getValue() { return value; getValue - 是一个对象的方法,它返回 Number 对象的实际值 getRandomNumber - 是一个静态方法(或子例程),可以在没有任何现有 Number 实例的情况下调用。
    【解决方案4】:

    所以,每个子程序要么包含在一个类中,要么包含在一个对象中

    该陈述在技术上并非 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
    
  • 【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-30
      • 2011-04-23
      • 1970-01-01
      • 1970-01-01
      • 2011-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多