简体   繁体   English

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

[英]Difference between Static and Non-Static methods/Subroutines

I was reading a java book, where I came across this statement: 我正在读一本Java书籍,遇到了以下语句:

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

I'm really confused why does it say "class or in an object" 我真的很困惑,为什么说"class or in an object"

I would like some explanation. 我想要一些解释。

Let's try this example 让我们尝试这个例子

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
    }
}

This code will work (even if the demo variable is null ) because static method classMethod is contained within the class Demo . 该代码将起作用(即使demo变量为null ),因为静态方法classMethod包含在Demo类中。 The commented line will throw a NullPointerException because the method objectMethod is not contained in the class but in the object so will need an instance of Demo class to call it. 带注释的行将抛出NullPointerException因为方法objectMethod不包含在类中,但是包含在对象中,因此需要一个Demo类的实例来调用它。

Subroutine is a method written inside a class. 子例程是在类内部编写的方法。 We use them to do various tasks. 我们使用它们来执行各种任务。 That statement states that these methods/subroutines are written in an object or a class. 该声明指出这些方法/子例程是写在对象或类中的。

If we have an object instantiated, it will create new methods for every non-static method for that object which were defined in the class of the object. 如果我们实例化了一个对象,它将为该对象的类中定义的每个non-static方法创建新方法。 Hence those non-static methods/subroutines are in the object. 因此,那些non-static方法/子例程在对象中。

But if the class is a static class, we can't have any objects from it. 但是,如果类是static类,则不能有任何对象。 But we can use subroutines/methods of that class. 但是我们可以使用该类的子例程/方法。 So, they are in a Class 所以,他们在一个Class

That's what your statement says. 那就是你的声明所说的。

EDIT: 编辑:

I thought to give an example for this. 我想为此举一个例子。

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"
  }
}

Then, if you need to get the static String, all you have to do is 然后,如果您需要获取static String,那么您要做的就是

String staticString = ExampleClass.getStaticString();

Note that I havn't created an object from the ExampleClass Here. 请注意,我没有在此处的ExampleClass创建对象。 I just used the method. 我只是用这种方法。

But, if you need to get the String from the non-static method, you should instantiate an object first. 但是,如果需要从non-static方法获取String ,则应首先实例化一个对象。

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

static methods also known as class method. 静态方法也称为类方法。 Static method associated only with the class and not with any specific instance of that class(object). 仅与该类相关联的静态方法,而不与该类(对象)的任何特定实例相关联。

So, every subroutine is contained either in a class or in an object 因此,每个子例程都包含在类或对象中

The statement is technically not 100% correct. 该声明在技术上不是100%正确。

First of all, subroutines in java are commonly called methods. 首先,java中的子例程通常称为方法。 The following two terms are often used interchangeably: 以下两个术语经常互换使用:

  • Method : A subroutine working with an object instance, this . 方法 :处理对象实例this子例程。
  • Function : A subroutine not working with an object instance. 功能 :子例程不适用于对象实例。


    Here is an example scenario which should you get an idea what that means: 这是一个示例方案,您应该了解这意味着什么:

     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(ax - bx) + squared(ay - by)); } //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 } 

    Output : 输出

     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 
  • 声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

     
    粤ICP备18138465号  © 2020-2024 STACKOOM.COM