【问题标题】:This method must return a result of type int - [closed]此方法必须返回 int 类型的结果 - [关闭]
【发布时间】:2013-11-10 16:57:58
【问题描述】:

除了最后一种方法getPrice() 之外,一切都正常工作我正在返回int,但我一直收到同样的错误。此外,如果我将保修设置为 false,它仍然返回 (base+((base/100)*10))

public class Machinery extends SaleGroup {

private float serial;
public int base;
private static boolean hasWarranty;

public Machinery(String newItemDescription, float newProductCode,
        float newSerial, int newBasePrice) {

    super(newItemDescription, newProductCode);
    serial = newSerial;
    base = newBasePrice;

}

public boolean IncludeWarranty() {
    return hasWarranty=true;
}

public boolean ExcludeWarranty() {
    return hasWarranty=false;
}

public float getSerial() {
    return serial;
}



public int getPrice()
    {
        if (hasWarranty==true)
        {
            return (base+((base/100)*10));
        } 
        else if (hasWarranty==false) 
        {
            return base;
        }
    }
}

我有 3 个类,SaleGroup.java、Machinery.java 和 MachineryTest.java

public abstract class SaleGroup {

     private String item;
     private float code;

     //Constructor with name and code parameters for specifying 
     //access methods that return the name and code
     public SaleGroup(String newItemDescription, float newProductCode)
     {
          item = newItemDescription;
          code = newProductCode;
     }

     public String getItemDescription() 
     {
          return item;
     }

     public float getProductCode() 
     {
          return code;
     }

     public abstract int getPrice();

     public String toString()
     {
          return "Item " + item + "has product code " + code + " and price is" + getPrice();
     }

}

MachineryTest.java

import javax.swing.JOptionPane;
public class MachineryTest {
    public static void main(String[] args) {
        String newItemDescription = "Item";
        float newSerial = 4234;
        float newProductCode = 3424;
        int newBasePrice = 1000;
        boolean hasWarranty=true;

        Machinery test1 = new Machinery(newItemDescription, newProductCode,
                newSerial, newBasePrice);
        JOptionPane.showMessageDialog(
                null,
                "Item: " + test1.getItemDescription() + " Serial: "
                        + test1.getSerial() + " Code: "
                        + test1.getProductCode() + " Warranty Included: "
                        + hasWarranty + " Price " + test1.getPrice());
    }
}

*更新:*

除了最后一个方法 getPrice() 我返回 int 之外,一切都正常工作,但我一直收到同样的错误。此外,如果我将保修设置为 false,它仍然返回 (base+((base/100)*10))

【问题讨论】:

  • 我认为您将编译时错误与运行时错误混淆了
  • 下一次,请不要删除您之前的代码并用两行替换它,如果没有其余的上下文则无法理解。此外,如果原始问题得到解决,那么您可能应该将答案标记为已接受并提出新问题。

标签: java eclipse class methods this


【解决方案1】:

如果您的if 条件都不为真,则该方法不会返回任何内容。
编译器的可达性分析不够聪明,无法意识到bools 必须始终为truefalse(尤其是因为这并不完全正确)

您可以通过从 else 子句中删除 if 来解决此问题。
当你在它的时候,你也可以删除 == true 部分,这是无用的。

【讨论】:

  • 好的,按照你告诉我的做,但是根据保修是否真实,基础不会改变。如果保修为真,我需要基数为 (base+((base/100)*10)) 否则返回基数..即如果基数为 1000 并且保修为真则返回 1100 如果保修为假则返回 1000
  • 代码工作正常,但我们不能对代码应该做什么的规范做出假设。但是,如果这是该方法的结果,那么在返回它之前将计算值分配给 base 是很容易的。但是,如果您这样做,您的方法会做两件事:1)计算新价格和 2)返回价格。最好将其拆分为 2 种方法。
【解决方案2】:

问题是编译器无法解决这个问题:

if (hasWarranty == true) {
   ...
} else if (hasWarranty == false) {
   ...
}

将始终准确执行这些路径中的一个。它认为您可能会到达if 语句的结尾而不使用任何一个分支,这意味着您可以在不返回任何内容的情况下到达方法的结尾。实际上,hasWarranty 有可能以 false 开头,然后另一个线程在执行第二个条件之前将其更改为 true

您可以删除第二个条件:

if (hasWarranty == true)  {
    ...
} else {
    ...
}

您还可以删除与布尔文字的比较:

if (hasWarranty) {
    ...
} else {
    ...
}

您还应该考虑使用条件运算符

public int getPrice() {
    return hasWarranty ? base + ((base/100) * 10) : base;
}

【讨论】:

    【解决方案3】:

    添加到 SLaks 答案只需像这样更改代码,即可成功编译:

     if (hasWarranty)
     {
          return (base+((base/100)*10));
     }
     else 
     {
          return base;
     }
    

    第二个if 是多余的。

    【讨论】:

    • @BackSlash,是的,我编辑了。 :)
    • 好的,按照你告诉我的做,但是根据保修是否真实,基础不会改变。如果保修为真,我需要基数为 (base+((base/100)*10)) 否则返回基数..即如果基数为 1000 并且保修为真则返回 1100 如果保修为假则返回 1000
    【解决方案4】:
    public int getPrice()
    {
        if (hasWarranty==true)
        {
             return (base+((base/100)*10));
        }
        else {
             return base;
        }
    }
    

    如果您已经在测试真案例,则 else 将自动成为假案例。只有两种可能的情况,真假。这样编译就知道总会有返回的东西。如果你的代码,编译不知道代码是否会返回任何东西,因为返回是用条件封装的。

    【讨论】:

    • 你可能想说为什么这样更好。
    • 好的,按照你告诉我的做,但是根据保修是否真实,基础不会改变。如果保修为真,我需要基数为 (base+((base/100)*10)) 否则返回基数..即如果基数为 1000 并且保修为真则返回 1100 如果保修为假则返回 1000
    • 检查@Peter Lawry 的答案。他有你的解决方案。
    【解决方案5】:
    public int getPrice()
    {
         if (hasWarranty==true)
         {
              return (base+((base/100)*10));
         }
         else if (hasWarranty==false) {
              return base;
    
         }
    }
    

    如果ifelse-if 都是false,则该函数无法评估返回任何内容,直到运行时才能评估它们中的任何一个true。因此,函数体getPrice() 可以正常完成并导致编译时错误。

    这是在jls-8.4.7 Method body中指定的:

    如果一个方法被声明为一个返回类型,那么一个编译时 如果方法的主体可以正常完成,则会发生错误。在 换句话说,具有返回类型的方法只能通过使用 提供返回值的 return 语句;不允许 “从身体的末端掉下来”

    所以:

    public int getPrice()
        {
             if (hasWarranty==true)
             {
                  return (base+((base/100)*10));
             }
    
           return base;
        }
    

    【讨论】:

      【解决方案6】:

      编译器不知道第二个if 语句是多余且毫无意义的。一般来说,如果代码混淆了编译器,那么它的代码就会混淆。你可以写

      public int getPrice() {
           if (hasWarranty==true) {
                return (base+((base/100)*10));
           }
           return base;
      }
      

      public int getPrice() {
           return base + (hasWarranty ? (base/100)*10 : 0);
      }
      

      顺便说一句,/100*10*10/100/10 不一样,我怀疑你想增加 10%,最好的方法是 base/10

      public int getPrice() {
           return base + (hasWarranty ? base/10 : 0);
      }
      

      拥有getPrice() 方法不会神奇地更改base 字段。如果你想要价格,你需要调用方法。

      public class Priced {
          int base = 1000;
          boolean hasWarranty = true;
      
          public static void main(String[] args) {
              final Priced priced = new Priced();
              System.out.println("price: " + priced.getPrice() + ", hasWarranty: " + priced.hasWarranty);
              priced.hasWarranty = false;
              System.out.println("price: " + priced.getPrice() + ", hasWarranty: " + priced.hasWarranty);
          }
      
          public int getPrice() {
              return base + (hasWarranty ? base / 10 : 0);
          }
      }
      

      打印

      price: 1100, hasWarranty: true
      price: 1000, hasWarranty: false
      

      【讨论】:

      • 谢谢彼得,我按照你告诉我的那样尝试了,但仍然遇到同样的问题.. 保修设置为 true,但它返回基数为 1000 而不是 1100...:/
      • @JohnSmith 在这种情况下,您做错了什么,例如获取base 而不是调用getPrice(),请参阅我的更新答案。
      • JOptionPane.showMessageDialog(null,"Item: "+test1.getItemDescription() + " Serial: "+ test1.getSerial() + " Code: "+ test1.getProductCode() + " 包含保修: "+ hasWarranty + " Price " + test1.getPrice());
      • @JohnSmith 你能加入test1.hasWarranty吗?
      • 我希望 hasWarranty 是非静态的。如果这是一个全局设置,使用它/改变它的方法也应该是static
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-25
      • 2018-03-08
      • 2013-09-02
      • 2013-12-18
      • 2015-09-25
      • 2013-11-24
      相关资源
      最近更新 更多