开发者

If user passes a primitive type argument to println(), what exactly happens behind the scene?

If user passes a primitive type argument to println(), what exactly happens behind the scene? e.g.

int i =1;

System.out.println("My Int"+i);

//and in

System.out.println(i)

How does it print "My In开发者_运维技巧t 1" and "1", even though it needs a String object?

updated..

What I think is AutoBoxing comes into play. Is that true, too?


System.out is a PrintStream. PrintStream has plenty of overloads for println, suche as println(int) or println(String), so the compiler will simply choose the most appropriate.

What happens in your first example is that you construct a new String using string concatenation of "My Int" and i and pass that String to the println method. That method needs not know how to "print concatenated String values", because it simply gets a normal String object.


System.out.println("My Int"+i);

equals

System.out.println(new StringBuilder().append("My Int").append(i).toString();

For example :

public class Main{
  public static void main(String[] ar){
    int i = 10;
    System.out.println("My Int"+i);
  }
}

now observe the code

public static void main(java.lang.String[]);
  Code:
   0:   bipush  10
   2:   istore_1
   3:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   6:   new     #3; //class java/lang/StringBuilder
   9:   dup
   10:  invokespecial   #4; //Method java/lang/StringBuilder."<init>":()V
   13:  ldc     #5; //String My Int
   15:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/
String;)Ljava/lang/StringBuilder;
   18:  iload_1
   19:  invokevirtual   #7; //Method java/lang/StringBuilder.append:(I)Ljava/lan
g/StringBuilder;
   22:  invokevirtual   #8; //Method java/lang/StringBuilder.toString:()Ljava/la
ng/String;
   25:  invokevirtual   #9; //Method java/io/PrintStream.println:(Ljava/lang/Str
ing;)V
   28:  return


It does not need a String object, and there is no autoboxing at play here, either. There are methods for primitive types as well:

public void print(int i)

Print an integer. The string produced by String.valueOf(int) is translated into bytes according to the platform's default character encoding, and these bytes are written in exactly the manner of the write(int) method.


System.out is a PrintStream which has overloaded println methods for all primitive types, String and Object.


Actually println doesn't need only a String object. It is defined for int too.

EDIT:

how : println is an overloaded method. There are different version of it:

public void println(int x) {
     print(x);

} public void println(long x) {} ...

//that is what it does
public void print(int i) {
write(String.valueOf(i));
}


The principle is called method overloading. You can define multiple methods with the same name, as long as the parameter list is different.

public class YourClass() {
    public int yourMethod(Object param) {return 0};
    // allowed: other parameters
    public int yourMethod(int i) {return 1};
    // allowed: wrapper classes are different enough
    public int yourMethod(Integer i) {return 2};
    // allowed: wrapper classes are different enough
    // not allowed: same parameter list, but different return type
    public float yourMethod(int i) {return 0.5f}; /* COMPILE ERROR */
}

When invoking the method, the compiler chooses the best fitting method.

YourClass obj = new YourClass();
Integer i = 1; // auto boxing
obj.yourMethod(i);            // returns 2
obj.yourMethod(i.intValue()); // returns 1
obj.yourMethod((Object)i);    // returns 0
obj.yourMethod(0.5);          // COMPILE ERROR, there is no yourMethod(double)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜