--- c:\java\jdk1.7\src\java\lang\String.java	2008-09-11 00:55:24.000000000 +0200
+++ c:\Proyectos\jdk1.7.0_optimizado\src\java\lang\String.java	2008-10-01 00:23:05.112571700 +0200
@@ -189,7 +189,8 @@
      * @param  value
      *         The initial value of the string
      */
-    public String(char value[]) {
+    // Modified argument declaration as proposed by Ulf Zibis
+    public String(char... value) {
         int size = value.length;
         this.offset = 0;
         this.count = size;
@@ -639,7 +640,124 @@
         this.offset = result.offset;
     }
 
+    /** 
+     * 
+     * @since  1.7
+     */
+    public String(StringAppender appender) {
+        String result = appender.toString();
+        this.value = result.value;
+        this.count = result.count;
+        this.offset = result.offset;
+    }
+    
+    /**
+     * Creates a new String from a String array.
+     * with the same result as "new StringBuilder().append().append()...toString()".
+     * 
+     * This is actually an optimized specialization of the
+     * <code>public String(Object...)</code> constructor.
+     * 
+     * @param strs      The String array
+     * @throws          NullPointerException if <code>objs</code> is <code>null</code>
+     *                  (but its elements can be null)
+     * 
+     * @since  1.7
+     */
+    public String(String... strs) {
+        // 1. Calculates the needed array length...
+        int totalSize = 0;
+        for (String str : strs)
+            totalSize += (str==null) ? 4 : str.count; // "null".count = 4
+        // 2. ...And copies the char[] values
+        char[] newValue = new char[totalSize];
+        copyValuesInto(strs, newValue, 0, strs.length);
+        this.offset = 0;
+        this.count = totalSize;
+        this.value = newValue;
+    }
+
+    /**
+     * Creates a new String from two.
+     * with the same result as "new StringBuilder().append(str0).append(str1).toString()".
+     * 
+     * This is actually an optimized specialization of the
+     * <code>public String(String...)</code> constructor.
+     * 
+     * @param str0      
+     * @param str1      
+     * 
+     * @since  1.7
+     */
+    public String(String str0, String str1) {
+        if (str0==null) str0 = "null";
+        if (str1==null) str1 = "null";
+        // 1. Calculates the needed array length...
+        int str0Count = str0.count;
+        int str1Count = str1.count;
+        int totalSize = str0Count + str1Count;
+        // 2. ...And copies the char[] values
+        char[] newValue = new char[totalSize];
+        System.arraycopy(str0.value, str0.offset, newValue, 0, str0Count);
+        System.arraycopy(str1.value, str1.offset, newValue, str0Count, str1Count);
+        this.offset = 0;
+        this.count = totalSize;
+        this.value = newValue;
+    }
 
+    /**
+     * This is actually an optimized specialization of the
+     * <code>public String(String...)</code> constructor.
+     * 
+     * @since  1.7
+     */
+    public String(String str0, String str1, String str2) {
+        if (str0==null) str0 = "null";
+        if (str1==null) str1 = "null";
+        if (str2==null) str2 = "null";
+        // 1. Calculates the needed array length...
+        int str0Count = str0.count;
+        int str1Count = str1.count;
+        int str2Count = str2.count;
+        int totalSize = str0Count + str1Count + str2Count;
+        // 2. ...And copies the char[] values
+        char[] newValue = new char[totalSize];
+        System.arraycopy(str0.value, str0.offset, newValue, 0, str0Count);
+        System.arraycopy(str1.value, str1.offset, newValue, str0Count, str1Count);
+        System.arraycopy(str2.value, str2.offset, newValue, str1Count, str2Count);
+        this.offset = 0;
+        this.count = totalSize;
+        this.value = newValue;
+    }
+    
+    /**
+     * This is actually an optimized specialization of the
+     * <code>public String(String...)</code> constructor.
+     * 
+     * @since  1.7
+     */
+    public String(String str0, String str1, String str2, String str3) {
+        if (str0==null) str0 = "null";
+        if (str1==null) str1 = "null";
+        if (str2==null) str2 = "null";
+        if (str3==null) str3 = "null";
+        // 1. Calculates the needed array length...
+        int str0Count = str0.count;
+        int str1Count = str1.count;
+        int str2Count = str2.count;
+        int str3Count = str3.count;
+        int totalSize = str0Count + str1Count + str2Count + str3Count;
+        // 2. ...And copies the char[] values
+        char[] newValue = new char[totalSize];
+        System.arraycopy(str0.value, str0.offset, newValue, 0, str0Count);
+        System.arraycopy(str1.value, str1.offset, newValue, str0Count, str1Count);
+        System.arraycopy(str2.value, str2.offset, newValue, str1Count, str2Count);
+        System.arraycopy(str3.value, str3.offset, newValue, str2Count, str3Count);
+        this.offset = 0;
+        this.count = totalSize;
+        this.value = newValue;
+    }
+    
     // Package private constructor which shares value array for speed.
     String(int offset, int count, char value[]) {
         this.value = value;
@@ -647,6 +765,55 @@
         this.count = count;
     }
 
+    // Package private. Used by StringAppender
+    // Returns the value (shared if offset=0 and count==value.length, else a copy)
+    char[] getValue() {
+        if (offset==0 && count==value.length)
+            return value;
+        else
+            return Arrays.copyOfRange(value, offset, offset+count);
+    }
+
+    // Code shared by the String(String...) constructor, join and StringAppender.toString()
+    // 
+    // @param strs  Precondition: (strs!=null)
+    // @param dst   Precondition: (dst!=null) && (dst.length is enought)
+    static void copyValuesInto(String[] strs, char[] dst, int dstBegin, int numStrs) {
+        int pos = dstBegin;
+        for (int i = 0; i < numStrs; i++) {
+            String str = strs[i];
+            if (str==null) {
+                System.arraycopy("null".value, 0, dst, pos, 4);
+                pos += 4;
+            }
+            else {
+                int cnt = str.count;
+                if (cnt==1)
+                    dst[pos++] = str.value[str.offset];
+                else {
+                    int off = str.offset;
+                    char[] val = str.value;
+                    System.arraycopy(val, off, dst, pos, cnt);
+                    pos += cnt;
+                }
+            }
+        }
+    }
