【问题标题】:Java - About float, long, intJava - 关于浮点数、长整数、整数
【发布时间】:2013-09-26 08:11:58
【问题描述】:

我有两种类似的方法,但它们的工作方式略有不同。 注意:getBytesDownloaded()、getFileSize() 返回long。

此方法返回的整数值完全符合我的预期(例如:51)

public int getPercentComplete() throws IOException
    {
        int complete = (int) Math.round(this.getBytesDownloaded()*100 / this.getFileSize());
        return complete;
    }

但是这个方法在运行时不会返回任何值(即使我将 int 更改为 long),尽管它编译正常:

public int getCurrentSpeed() throws IOException
{
    long KBytesDownloaded = this.getBytesDownloaded() / 1024;
    currentTime = System.currentTimeMillis();
    int speed =  (int) Math.round(KBytesDownloaded * 1000 / (currentTime - startTime));
    return speed;
}

错误:

Exception in thread "Timer-0" java.lang.NoSuchMethodError: com.myclasses.Downloa
d.getCurrentSpeed()F
        at test$2.run(test.java:87)
        at java.util.TimerThread.mainLoop(Timer.java:555)
        at java.util.TimerThread.run(Timer.java:505)

为了解决这个问题,我把int改成float,效果很好(eg:300.0)

public float getCurrentSpeed() throws IOException
    {
        long KBytesDownloaded = this.getBytesDownloaded() / 1024;
        currentTime = System.currentTimeMillis();
        float speed =  KBytesDownloaded * 1000 / (currentTime - startTime));
        return speed;
    }

为什么两个相似的方法不返回相同的类型值?谢谢。

【问题讨论】:

  • “不返回任何值”是什么意思?
  • 除非抛出异常,否则该方法不可能不“返回任何值”,在这种情况下,您应该发布堆栈跟踪。你的意思是它返回零?
  • 对不起,我忘记了错误:线程“Timer-0”中的异常 java.lang.NoSuchMethodError: com.myclasses.Downloa d.getCurrentSpeed()F at test$2.run(test.java: 87) 在 java.util.TimerThread.mainLoop(Timer.java:555) 在 java.util.TimerThread.run(Timer.java:505)
  • 天哪。这只是意味着您需要重新编译所有内容。与这里的代码无关。
  • @user1780606 您的实现中仍然出现截断错误。 1000(currentTime - startTime) 都不是 float,因此它们的除法将产生截断的 Long 值(不精确)。查看stackoverflow.com/a/19022838/1433665

标签: java int long-integer


【解决方案1】:

NoSuchMethodError 在您调用类中的方法时抛出,但该类没有该方法。当您已经有一个已编译的程序,然后在一个类中更改方法声明而不重新编译依赖它的类时,就会发生这种情况。

在这种情况下,您的 test 类被编译为在 Download 类中调用 float getCurrentSpeed()。然后您将方法返回类型更改为int,而无需重新编译test 类,这样test 所需的方法就不再存在,因此NoSuchMethodError。当您将返回类型更改回float 时,问题就消失了。

如果你更改了Download中的返回类型,别忘了重新编译test

【讨论】:

    【解决方案2】:

    我已经使用一些随机的 int、long 和 double 变量测试了您的代码。

    虽然我没有尝试过很多测试用例,

    他们似乎对我都很好。

    不返回任何值是什么意思?

    ================================================ ===

    如果是no method错误,请重新编译运行。

    如果这没有帮助,请检查您是否调用了正确的函数

    【讨论】:

      【解决方案3】:

      Math.round()floatdouble 作为参数。

      KBytesDownloaded * 1000 / (currentTime - startTime)
      

      在这个表达式中,KBytesDownloadedLong

      问题是像 Long/Long 这样的除法会截断小数点后的浮点值。

      确保将类型转换为 floatdouble 以防止在四舍五入之前被截断。

       int speed =  Math.round(KBytesDownloaded * (float) 1000 / (currentTime - startTime));
      

      【讨论】:

      • Math.round() 实际上将floatdouble 作为参数。
      • @millimoose 可以,但(Long/Long) 会截断小数点后的值。
      • @TheKojuEffect 那么为什么您的答案没有提到这是一个问题以及它的作用?正如所写,它暗示参数类型错误,这不是问题。
      • @millimoose 请检查我的新答案。
      猜你喜欢
      • 2011-01-10
      • 2011-05-29
      • 2011-01-04
      • 2017-07-26
      • 2020-07-26
      • 2016-11-06
      • 1970-01-01
      • 2017-12-09
      • 2013-09-14
      相关资源
      最近更新 更多