方法应返回boolean,返回int

时间:2015-02-18 10:49:45

标签: java methods bytecode

我必须创建一个与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;
}

您可以在方法签名中看到它应该返回boolean,但它确实返回ì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,它返回一个int。

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

怎么可能?是否存在隐式演员?

感谢。

2 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:4)

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

  

<强> 2.3.4。布尔类型

     

虽然Java虚拟机定义了一个布尔类型,但它只提供非常有限的支持。没有Java虚拟机指令专门用于对布尔值的操作。相反,Java编程语言中对布尔值进行操作的表达式被编译为使用Java虚拟机int数据类型的值

你可以自己检查一下:

$ 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        <------------
}