【问题标题】:Java -- method returning correct value when called outside of class but not when called from inside?Java - 在类外部调用但从内部调用时返回正确值的方法?
【发布时间】:2021-02-27 23:49:12
【问题描述】:

我正在做 Java 的基础知识,所以在做一个更大的程序时,我遇到了这个问题,我想我会尝试在一个单独的程序中修复它。但这仍然让我感到困惑。 我已将问题分解为我无法解释的一件事 这是代码。

package Basics;

import java.util.Scanner;
import java.util.Arrays;

public class Polygon {

    Scanner input = new Scanner(System.in);
    int num;

    Polygon(int n) {
        this.num = n;
    }

    int[] getSides() {
        int[] sides = new int[this.num];
        for (int i = 0; i < this.num; i++) {
            System.out.println("Enter length of side " + (i + 1));
            sides[i] = input.nextInt();
        }
        //System.out.println(Arrays.toString(sides));
        return sides;
    }

    int[] sides = this.getSides();

}

class runner {

    public static void main(String[] args) {
        Polygon rectangle = new Polygon(4);
        int[] sides = rectangle.getSides();
        System.out.println(Arrays.toString(sides));
        System.out.println(Arrays.toString(rectangle.sides));
        
    }

}

这是输出

run:
Enter length of side 1
5
Enter length of side 2
4
Enter length of side 3
3
Enter length of side 4
2
[5, 4, 3, 2]
[]
[]
BUILD SUCCESSFUL (total time: 3 seconds)

正如您所见,当从类外调用时,getSides() 方法返回正确的值,即用户输入的任何值。但从里面它没有? 我很确定这在某种程度上是一个愚蠢或菜鸟的问题,而且我缺少一些巨大的东西,但我真的需要帮助 这是什么原因造成的,我该如何解决?

【问题讨论】:

  • 在java中的类名以大写字母开头,所以最好把runner写成Runner
  • 对不起!不知道

标签: java arrays class oop methods


【解决方案1】:

在函数getSides() 中,您定义了一个新数组sides,您没有将其称为您定义为int[] sides = this.getSides(); 的类实例变量

int[] getSides() {
    sides = new int[this.num];
    for (int i = 0; i < this.num; i++) {
        System.out.println("Enter length of side " + (i + 1));
        sides[i] = input.nextInt();
    }
    // System.out.println(Arrays.toString(sides));
    return sides;
}

完整代码:

import java.util.Arrays;
import java.util.Scanner;

public class Polygon {
    Scanner input = new Scanner(System.in);
    int num;

    Polygon(int n) {
        this.num = n;
    }

    int[] getSides() {
        this.sides = new int[this.num];
        for (int i = 0; i < this.num; i++) {
            System.out.println("Enter length of side " + (i + 1));
            sides[i] = input.nextInt();
        }
        // System.out.println(Arrays.toString(sides));
        return sides;
    }

    int[] sides = this.getSides();
}

跑步者类:

public class Runner {
    public static void main(String[] args) {
        Polygon rectangle = new Polygon(4);
        int[] sides = rectangle.getSides();
        System.out.println(Arrays.toString(sides));
        System.out.println(Arrays.toString(rectangle.sides));
    }
}

要获得更好的代码,您可以编写Polygon 类,如下所示:

public class Polygon {
    Scanner input = new Scanner(System.in);
    int num;
    int[] sides;

    Polygon(int n) {
        this.num = n;
        this.sides = new int[this.num];
    }

    int[] getSides() {
        for (int i = 0; i < this.num; i++) {
            System.out.println("Enter length of side " + (i + 1));
            sides[i] = input.nextInt();
        }
        System.out.println(Arrays.toString(sides));
        return sides;
    }
}

【讨论】:

  • 我认为这行不通。尝试移动 System.out.println(Arrays.toString(rectangle.sides));在 getSides 调用之前,你也会得到空数组。
  • 我将代码 int[] sides = new int[this.num]; 更改为 sides = new int[this.num]; 并且它工作正常。
  • 是的,它适用于给定的测试用例。但它不会在创建对象时初始化边字段。
  • @SatvikGupta 我为您的问题添加了一个更好、更干净的代码,以防止出现逻辑错误。
  • @SatvikGupta 称为阴影。有关更多信息,请参阅tutorialspoint.com/what-is-variable-shadowing-in-java - 基本上当在不同范围内有两个同名变量时,使用最直接的范围
【解决方案2】:
public class Polygon {
    Scanner input = new Scanner(System.in);
    int num;    // Java default value for integers is zero
 
    Polygon(int n) {
        this.num = n; // The value is changed when an object is created;
    }

    int[] getSides() {
        int[] sides = new int[this.num]; 
        for (int i = 0; i < this.num; i++) {
            System.out.println("Enter length of side " + (i + 1));
            sides[i] = input.nextInt();
        }
        return sides;
    }

    int[] sides = this.getSides(); // This method call to getSides will be executed before the Constructor, using all the instance variables(so, the variable num is 0)
}

你的问题,是你分配变量边调用方法getSides(),因为这个分配将在构造函数之前运行,变量num是0(默认value),所以没有迭代。

示例在构造函数之前执行的方法

public class Polygon {

    Scanner input = new Scanner(System.in);
    int num;
    int[] sides = this.getSides();  // Assign a variable with  the return of a method, this is executed before the constructor

    Polygon(int n) {
        System.out.println("I am the constructor");
        this.num = n;
    }

    int[] getSides() {
        System.out.println("I will be executed before the constructor");
        int[] sides = new int[this.num];
        for (int i = 0; i < this.num; i++) {
            System.out.println("Enter length of side " + (i + 1));
            sides[i] = input.nextInt();
        }
        //System.out.println(Arrays.toString(sides));
        return sides;
    }



    public static void main(String[] args) {
        new Polygon(5);
    }

【讨论】:

  • 那么我如何让构造函数首先被调用?
  • 什么?构造函数是特殊方法,它在其他人之前执行。多边形矩形 = 新多边形(4);它将执行构造函数。
  • 我一头雾水,你说getSides的方法调用是在构造函数之前执行的
  • 是的,在构造函数之前执行。构造函数是创建对象时执行的第一个方法。您的问题是您使用方法的结果分配了一个变量,而该方法使用了另一个实例变量。因此,该方法使用您声明和初始化的值执行(如果您没有定义,将使用默认值)
  • 兄弟,我将编辑我的答案并举个例子。看看
猜你喜欢
  • 2012-02-21
  • 2019-04-16
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 2021-04-30
  • 1970-01-01
  • 1970-01-01
  • 2014-08-28
相关资源
最近更新 更多