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)
精彩评论