【问题标题】:Method error in JavaJava中的方法错误
【发布时间】:2014-03-28 08:58:30
【问题描述】:

这可能很简单或相当困难...我不知道这两种方式。 这是我的代码:

package looping;

import java.util.Scanner;

public class PayrollMethods2 {

    public static void main(String[] args) {

        int hours = 0;
        double wr = 0;
        double pay;

        getData(hours, wr);

        pay = calculatePay(hours, wr);

        System.out.println(pay);
        // TODO Auto-generated method stub

    }


    public static void getData(Integer hours, Double wr)
    {
        Scanner kb = new Scanner(System.in);


        System.out.print("Please enter your wage rate ");
        wr = kb.nextDouble();

        System.out.print("Please enter your hours work ");
        hours = kb.nextInt();
    }



    public static double calculatePay(int hours, double wr)
    {
        if(hours <= 40)
            return hours * wr;
        else
            return (40 * wr) + ((hours - 40) * (1.5* wr));
    }

}

我想返回方法“getData()”,这样当我在键盘上输入小时和 wr 时,它会返回总数。但是,无论我按什么,它都会返回 0.0。我知道这与我为变量赋值 0 以及该方法是“void”有关。但我不知道如何修改 getData() 方法以使其返回正确的值。

【问题讨论】:

  • 一方面,Java 是按值传递的。
  • 对不起JAVA新手,但我将主要方法更改为“getData(Interger,Double);”..我认为这就是你的意思但仍然没有,但应该没有问题在 main 中初始化的赋值变量?
  • @Circuuspeatnutz:这是范围和价值传递的问题。您正在分配参数。如果您使用像 Netbeans 这样的 IDE,它会警告您这一点。由于您没有将值存储在该方法之外的任何位置,因此它们基本上会在getData 中被丢弃。
  • 感谢您的帮助!我现在明白通过值了哈哈。
  • @SotiriosDelimanolis 按值传递从未阻止任何人修改函数内部的对象。这里的问题是Integer 对象是不可变的。

标签: java eclipse class methods


【解决方案1】:

您面临的问题是因为变量 hours & wr 是按值传递给 getData() 的,所以 getData 函数有自己的变量 hours & wr 的副本。

主要:(初始化)

Variable    Value    Memory Address
hours         0       44444
wr            0.0     55555

获取数据: hours & wr 与 main 不同,所以他们有不同的地址

Variable    Value    Memory Address
hours         0       66666
wr            0.0     77777

用户现在输入值:hours - 10 , wr - 20

Variable    Value    Memory Address
hours         10       66666
wr            20.0     77777

ma​​in : 当控制权回到 main 时, hours & wr 的值仍然为 0

Variable    Value    Memory Address
hours         0       44444
wr            0.0     55555

解决方案:

这个问题可以通过将工资信息封装到一个对象中然后传递该对象来解决(对象在Java中通过引用传递):

class Salary
{
  int hours;
  double wr;
}

现在在 getData 中,您可以根据用户输入信息创建数据 Salary 对象并将该对象传递给 calculatePay

public static Salary getData()
{
    Scanner kb = new Scanner(System.in);
    Salary sal = new Salary();

    System.out.print("Please enter your wage rate ");
    sal.wr = kb.nextDouble();

    System.out.print("Please enter your hours work ");
    sal.hours = kb.nextInt();

    return sal;
}

public static double calculatePay(Salary sal)
{
}

【讨论】:

  • 谢谢你!我想我理解变量错误。这是因为 hours 和 wr 的定义值为“0”,对吗?
  • 不,因为你是按值传递这些变量的。所以你在 getData 中对它们所做的任何修改都不会被传播
【解决方案2】:

通常,当您在函数内部修改对象时,更改会反映在该函数外部。为什么整数对象的行为不同?看看下面的代码。

psv main (String[] args) {
    Integer i = new Integer(1);
    increment(i);
    System.out.println(i); // Prints 1!
}

void increment(Integer i) { i = i + 1; }

我们预计会打印 2,但会打印 1。这是因为整数是不可变的

通常,如果您将一个对象传递给一个函数并修改其内容,您会得到一个修改后的对象。因为,当修改不可变对象时,会创建一个全新的对象。如果你创建了一个全新的对象,你就不再修改旧的对象了!

因此,递增我们的 Integer 创建了一个全新的 Integer,它是递增函数的本地变量。

【讨论】:

  • 这与不变性没有任何关系。如果您使用了一些自定义的可变类型而不是Integer,例如Custom,并更改了引用,则该更改不会反映在调用代码中。这是 Java 按值传递的结果。见here
  • @SotiriosDelimanolis 如果我创建了一个自定义对象并尝试为其分配一个原始int,我的程序可能会崩溃。神奇之处在于Integer 的自定义= 运算符。为什么它需要自定义赋值运算符?因为它没有setValue() 方法。为什么它没有setValue() 方法?因为它是不可变的。
  • 你误会了。给定public class Custom {},如果您传递绑定到方法参数Custom cCustom 对象并在方法内部执行c = new Custom(),则该更改不会反映在调用代码中。这就是价值传递的意义所在。 Integer 是不可变的,很好。但这里的根本问题是重新分配对参数变量的引用并没有反映在用于调用方法的参数中。 Java 是按值传递的。 (在cmets中很难说这一切,在聊天中会更容易。)
  • @SotiriosDelimanolis OP 从未使用过 new 运算符,我也没有使用过,因此您在示例中将苹果与橙子进行比较。
  • 同样new 没有区别,它是=,重新分配引用,确实如此。 hours = ...
【解决方案3】:

Java 是 pass-by-value。看起来您正在尝试修改参数,这些参数是本地范围的,因此您不会看到 main 中的更改。

Java 不允许多次返回,因此您要么必须创建一个类来传回,要么可以将来自 getData 方法的调用放入 main 方法中。

【讨论】:

    【解决方案4】:

    您需要在类中将 wr 和 hours 变成静态变量,或者您需要有两个 getData 方法并让它们返回,或者您需要创建一个单独的对象来存储 wr 和 hours。

    当你调用一个方法时,变量被复制到方法中。因此,当您在方法内更改它们时,它不会更改方法外的任何内容。 (如果你传入一个对象,那么对该对象的引用是按值传递的,因此在这种情况下,将看到对象内部的变化)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-13
      • 2013-09-03
      • 1970-01-01
      • 2016-04-13
      • 2013-07-07
      • 2017-09-07
      • 1970-01-01
      相关资源
      最近更新 更多