Am 05.06.2017 um 19:43 schrieb Philippe Mouawad:
On Monday, June 5, 2017, Felix Schumacher <felix.schumac...@internetallee.de>
wrote:
Hi all,
while looking at the javadocs for DataSourceElement, I found a couple of
things, that look odd to me.
a) Instead of string concatenation with "+" for static strings, often a
Stringbuilder is used. So instead of:
String result = "shared: " + shared + " user: " + username + ...
The code looks like
StringBuilder builder = new StringBuilder(40);
builder.append("shared: ").append(shared)
.append("user: ").append(username)
...
String result = builder.toString();
I think the compiler will generate the same code for the former and the
latter. To me the string concatenation looks cleaner.
Is there any reason to use the latter code for static strings?
If this part is intensive I am not sure perfs are not better with
StringBuilder
When you compile a class:
public class Test {
public static String builder(String a, String b) {
StringBuilder builder = new StringBuilder(10);
builder.append("a: ").append(a)
.append(" b: ").append(b);
return builder.toString();
}
public static String concat(String a, String b) {
return "a: " + a + " b: " + b;
}
public static void main(String[] args) {
System.out.println("Builder: " + builder("a", "b"));
System.out.println("Concatenation: " + concat("a", "b"));
}
}
You get the (de-)compiled class [javap -c Test.class]:
Compiled from "Test.java"
public class Test {
public Test();
Code:
0: aload_0
1: invokespecial #1 // Method
java/lang/Object."<init>":()V
4: return
public static java.lang.String builder(java.lang.String,
java.lang.String);
Code:
0: new #2 // class
java/lang/StringBuilder
3: dup
4: bipush 10
6: invokespecial #3 // Method
java/lang/StringBuilder."<init>":(I)V
9: astore_2
10: aload_2
11: ldc #4 // String a:
13: invokevirtual #5 // Method
java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
16: aload_0
17: invokevirtual #5 // Method
java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
20: ldc #6 // String b:
22: invokevirtual #5 // Method
java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
25: aload_1
26: invokevirtual #5 // Method
java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
29: pop
30: aload_2
31: invokevirtual #7 // Method
java/lang/StringBuilder.toString:()Ljava/lang/String;
34: areturn
public static java.lang.String concat(java.lang.String,
java.lang.String);
Code:
0: new #2 // class
java/lang/StringBuilder
3: dup
4: invokespecial #8 // Method
java/lang/StringBuilder."<init>":()V
7: ldc #4 // String a:
9: invokevirtual #5 // Method
java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
12: aload_0
13: invokevirtual #5 // Method
java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
16: ldc #6 // String b:
18: invokevirtual #5 // Method
java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: aload_1
22: invokevirtual #5 // Method
java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
25: invokevirtual #7 // Method
java/lang/StringBuilder.toString:()Ljava/lang/String;
28: areturn
public static void main(java.lang.String[]);
Code:
0: getstatic #9 // Field
java/lang/System.out:Ljava/io/PrintStream;
3: new #2 // class
java/lang/StringBuilder
6: dup
7: invokespecial #8 // Method
java/lang/StringBuilder."<init>":()V
10: ldc #10 // String Builder:
12: invokevirtual #5 // Method
java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: ldc #11 // String a
17: ldc #12 // String b
19: invokestatic #13 // Method
builder:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
22: invokevirtual #5 // Method
java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
25: invokevirtual #7 // Method
java/lang/StringBuilder.toString:()Ljava/lang/String;
28: invokevirtual #14 // Method
java/io/PrintStream.println:(Ljava/lang/String;)V
31: getstatic #9 // Field
java/lang/System.out:Ljava/io/PrintStream;
34: new #2 // class
java/lang/StringBuilder
37: dup
38: invokespecial #8 // Method
java/lang/StringBuilder."<init>":()V
41: ldc #15 // String Concatenation:
43: invokevirtual #5 // Method
java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
46: ldc #11 // String a
48: ldc #12 // String b
50: invokestatic #16 // Method
concat:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
53: invokevirtual #5 // Method
java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
56: invokevirtual #7 // Method
java/lang/StringBuilder.toString:()Ljava/lang/String;
59: invokevirtual #14 // Method
java/io/PrintStream.println:(Ljava/lang/String;)V
62: return
}
You will notice, that the methods concat() and builder() compile down to
the same class instructions, with one difference. The initialisation of
the StringBuilder is done with no argument in the concat() case and with
our "10" in the builder() one.
b) In the inner class DataSourceComponentImpl there is some (really
minor) code duplication in getConnectionInfo and getConnection. But my real
concern is, that getConnection checks for a null BasicDataSource, while
getConnectionInfo doesn't.
What is the logic behind this?
A bug :)
So it wouldn't harm to check for null on getConnectionInfo, right?
Felix