方法应该 return boolean, returns int

Method should return boolean, returns int

我必须创建一个类似于 JAR 中的方法。我没有代码,所以我懒得学习了。 我用的是JD-GUI,它告诉我,是:

private static boolean checkMe(Date paramDate, String paramString)
        throws REUException {
    int i = 1;
    int j, k;

    // unrelated stuff

    if (j > k)
        i = 0;
    return i;
}

你可以在方法签名中看到它应该 return 一个 boolean,但它实际上 return 一个 ìnt,这在 Java 中是不允许的]
所以,我认为 JD-GUI 有问题。

我尝试使用 javap 进行反汇编,但我仍然没有得到任何线索:

使用:javap -c -s -verbose -private Class

我得到:

private static boolean checkMe(java.util.Date, java.lang.String)   throws reu.exceptions.REUException;
  Signature: (Ljava/util/Date;Ljava/lang/String;)Z
  Code:
   Stack=4, Locals=7, Args_size=2
   0:   iconst_1
   1:   istore_2
   2:   getstatic   #34; //Field iniciado:Z
   5:   ifne    44
   8:   ldc_w   #35; //class reu/modulos/STDWDATES
   11:  dup
   12:  astore_3
   13:  monitorenter
   14:  getstatic   #34; //Field iniciado:Z
   17:  ifne    32
   20:  new #35; //class reu/modulos/STDWDATES
   23:  dup
   24:  invokespecial   #36; //Method "<init>":()V
   27:  pop
   28:  iconst_1
   29:  putstatic   #34; //Field iniciado:Z
   32:  aload_3
   33:  monitorexit
   34:  goto    44
   37:  astore  4
   39:  aload_3
   40:  monitorexit
   41:  aload   4
   43:  athrow
   44:  aconst_null
   45:  getstatic   #37; //Field AlmacenFechaCal:Ljava/util/HashMap;
   48:  aload_1
   49:  invokevirtual   #38; //Method java/util/HashMap.get:(Ljava/lang/Object;)Ljava/lang/Object;
   52:  if_acmpne   67
   55:  new #39; //class reu/exceptions/REUException
   58:  dup
   59:  bipush  58
   61:  bipush  17
   63:  invokespecial   #40; //Method reu/exceptions/REUException."<init>":(II)V
   66:  athrow
   67:  getstatic   #37; //Field AlmacenFechaCal:Ljava/util/HashMap;
   70:  aload_1
   71:  invokevirtual   #38; //Method java/util/HashMap.get:(Ljava/lang/Object;)Ljava/lang/Object;
   74:  checkcast   #41; //class reu/modulos/AlmancenFechas
   77:  astore_3
   78:  aload_3
   79:  invokevirtual   #42; //Method reu/modulos/AlmancenFechas.getFechaIni:()I
   82:  istore  4
   84:  invokestatic    #43; //Method java/util/Calendar.getInstance:()Ljava/util/Calendar;
   87:  astore  5
   89:  aload   5
   91:  aload_0
   92:  invokevirtual   #44; //Method java/util/Calendar.setTime:(Ljava/util/Date;)V
   95:  aload   5
   97:  iconst_1
   98:  invokevirtual   #45; //Method java/util/Calendar.get:(I)I
   101: istore  6
   103: iload   4
   105: iload   6
   107: if_icmple   112
   110: iconst_0
   111: istore_2
   112: iload_2
   113: ireturn
  Exception table:
   from   to  target type
    14    34    37   any
    37    41    37   any
  Exceptions: 
   throws reu.exceptions.REUException

我猜线索是113中的ireturn表达式。根据oracle documentation for ireturn,它return是一个int。

在这个 Casting conversions to primitive types 中,看起来像从 int 到 boolean 的转换,不像 C/C++,是不允许的。

这怎么可能?有隐式演员表吗?

谢谢。

JVM 将 booleans 表示为 ints:true1 表示,false0 表示。这就是编译后的代码使用整数的原因。

换句话说,如果您编写该方法并按如下方式使用 booleans(这可能是原始来源):

private static boolean checkMe(Date paramDate, String paramString)
       throws REUException {
   boolean i = true;
   int j, k;

    // unrelated stuff

    if (j > k)
        i = false;
    return i;
}

那么生成的字节码最后会包含ireturn

JVM 使用整数来表示布尔值。来自 JVM Specification §2.3.4:

2.3.4. The boolean Type

Although the Java Virtual Machine defines a boolean type, it only provides very limited support for it. There are no Java Virtual Machine instructions solely dedicated to operations on boolean values. Instead, expressions in the Java programming language that operate on boolean values are compiled to use values of the Java Virtual Machine int data type.

你可以自己看看:

$ cat Test.java
class Test {
    boolean m() {
        return true;    <------------
    }
}
$ javac Test.java 
$ javap -c Test
Compiled from "Test.java"
class Test {
  [...]     

  boolean m();
    Code:
       0: iconst_1      
       1: ireturn        <------------
}