Java 7ノート1を深く理解する


1.switch        

package com.chap1.switch_string;

/**
 * 
 *   Switch_String
 * 
 * @author ajan
 * @since 1.7.0_51
 * @version 1.0.0 2014 12 22 
 * 
 */

public class Title
{
    public String generate(String name, String gender)
    {
        String title = "";

        // case        
        switch (gender)
        {
            case " ":
                title = name + "   ";
                break;
            case " ":
                title = name + "   ";
                break;
            // case     null,    
            // case null;
            // break;
            default:
                title = name;
        }

        return title;
    }

    public static void main(String[] args)
    {
        Title title = new Title();

        System.out.println(title.generate("kobe", " "));
        //       null,       
        // System.out.println(title.generate("kobe", null));
    }
}

package com.chap1.switch_string;

/**
 * 
 * case       ,Java       Unicode    .->       Java    Java            ->
 *           Unicode       -> case             ,             ,      
 * 
 * <pre>
 *         
 *     1.         。Java                           ,           ,       
 *  2.            case  ,     ,                ,           
 *  3.    
 *      1.switch   case->    if
 *      2.switch   case,  default->    if/else
 *      3.  case->  Java7   case->      hash        
 *  4.  :Title.jad
 *      jad Title.class
 *     5.Title.jd  jd-gui     .
 *     6.           ,         :switch(s.hashCode())
 *  7. jad        ,+  StringBuilder.append     ->
 *  8.        swich_string->    ,      ,      ->  case           .       ,       .
 * </pre>
 * 
 * @author landon
 * @since 1.7.0_51
 * @version 1.0.0 2014 4 22 
 * 
 */

public class TitleDuplicate
{
    public String generate(String name, String gender)
    {
        String title = "";

        //     :Duplicate case,    case  ,         
        // \u7537 " " Unicode    
        switch (gender)
        {
        // case " ":
        // title = name + "   ";
        // break;
            case "\u7537":
                break;
            default:
        }

        return title;
    }
}


// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   Title.java

package com.chap1.switch_string;

import java.io.PrintStream;

public class Title
{

    public Title()
    {
    }

    public String generate(String name, String gender)
    {
        String title;
label0:
        {
            title = "";
            String s;
            switch((s = gender).hashCode())
            {
            default:
                break;

            case 22899: 
                if(!s.equals("\u5973"))
                    break;
                title = (new StringBuilder(String.valueOf(name))).append(" \u5973\u58EB").toString();
                break label0;

            case 30007: 
                if(s.equals("\u7537"))
                {
                    title = (new StringBuilder(String.valueOf(name))).append(" \u5148\u751F").toString();
                    break label0;
                }
                break;
            }
            title = name;
        }
        return title;
    }

    public static void main(String args[])
    {
        Title title = new Title();
        System.out.println(title.generate("kobe", "\u7537"));
    }
}

package com.chap1.switch_string;

import java.io.PrintStream;

public class Title
{
  public String generate(String name, String gender)
  {
    String title = "";
    String str1;
    switch ((str1 = gender).hashCode())
    {
    case 22899: 
      if (str1.equals(" ")) {
        break;
      }
    case 30007: 
      if ((goto 108) && (str1.equals(" ")))
      {
        title = name + "   ";
        return title;
        
        title = name + "   ";
      }
      break;
    }
    title = name;
    

    return title;
  }
  
  public static void main(String[] args)
  {
    Title title = new Title();
    
    System.out.println(title.generate("kobe", " "));
  }
}

2.        

package com.chap1.binary_literal;

/**
 * 
 *         
 * 
 * @author landon
 * @since 1.7.0_51
 * @version 1.0.0 2014 4 22 
 * 
 */

public class BinaryIntegralLiteral
{
    //           
    public void displayBinaryLiteral()
    {
        // 0b/0B     
        System.out.println(0b1001);
        System.out.println(0B1111);
        System.out.println(0b01111111);
    }

    //           
    public void displayOctalLiteral()
    {
        // 0  8  
        // 1 * 8 + 7 = 15
        System.out.println(017);
        // 1 * 8    + 2 * 8 + 7 = 87
        System.out.println(0127);
    }
    
    //            
    public void displayHexLiteral()
    {
        // 0x/0X  16  
        // a,b,c,d,e,f   10,11,12,13,14,15
        // 15 
        System.out.println(0xf);
        // 1 * 16 + 15 = 31
        System.out.println(0X1f);
        // 2 * 16 + 10 = 42
        System.out.println(0x2a);
    }
    

    public static void main(String[] args)
    {
        BinaryIntegralLiteral bil = new BinaryIntegralLiteral();
        
        bil.displayBinaryLiteral();

        bil.displayOctalLiteral();
        
        bil.displayHexLiteral();
    }
}

package com.chap1.binary_literal;

/**
 * 
 *            ->         ->    ->        ->               
 * ->           ->       
 * ->                          ->         , _100         ,         
 * 
 * @author landon
 * @since 1.7.0_51
 * @version 1.0.0 2014 4 22 
 * 
 */

public class Underscore
{
    public void display()
    {
        System.out.println(1_500_000);

        double value1 = 5_6.3_4;
        //         
        int value2 = 89_3__1;

        System.out.println(value1);
        System.out.println(value2);
    }

    public static void main(String[] args)
    {
        Underscore underscore = new Underscore();
        underscore.display();
    }
}
3.       

package com.chap1.exception_optimize;

/**
 * 
 * Java7   catch     ,           ,         “|”   ,        catch         
 * ->#throwManyExceptions
 *  :1.catch              ,                              ,        。
 * ->#throwSubExceptions
 * 2.  catch            ,                         (     “e”               )。
 * ->#throwIncludeRuntimeException
 * 3.                         ,                 。          
 * ->landon:                
 * ,                   ,        , #throwIncludeRuntimeException catch  
 *  NullPointerException        ,         (   jdk7     )
 * 
 * @author landon
 * @since 1.7.0_51
 * @version 1.0.0 2014 4 24 
 * 
 */

public class CatchManyExceptions
{
    //          
    public void throwManyExceptions() throws ExceptionA, ExceptionB, ExceptionC
    {

    }

    //      :D C   
    public void throwSubExceptions() throws ExceptionC, ExceptionD
    {

    }

    //      RunTimeException
    public void throwIncludeRuntimeException() throws NullPointerException,
            RuntimeException
    {

    }

    //        ,D,E  C   
    public void throw2SubExceptions() throws ExceptionD, ExceptionE
    {

    }

    public static void main(String[] args)
    {
        CatchManyExceptions catchManyExceptions = new CatchManyExceptions();
        try
        {
            // Ctrl + 1,Surround with try/multi-catch
            catchManyExceptions.throwManyExceptions();
        } catch (ExceptionA | ExceptionB e)
        {
            System.err.println("catch Exception A | B");
        } catch (ExceptionC e)
        {
            System.err.println("catch Exception C");
        }

        //         :The exception ExceptionD is already caught by the
        // alternative ExceptionC
        // try
        // {
        // catchManyExceptions.throwSubExceptions();
        // } catch (ExceptionD | ExceptionC e)
        // {
        // }

        //         : The exception ExceptionD is already caught by the
        // alternative ExceptionC
        // try
        // {
        // catchManyExceptions.throwSubExceptions();
        // } catch ExceptionC | ExceptionD e)
        // {
        // }

        //    jdk1.7       
        try
        {
            catchManyExceptions.throwSubExceptions();
        } catch (ExceptionD e)
        {
            e.printStackTrace();
        } catch (ExceptionC e)
        {
            e.printStackTrace();
        }

        //         :The exception NullPointerException is already caught by the
        // alternative RuntimeException
        // try
        // {
        // catchManyExceptions.throwIncludeRuntimeException();
        // } catch (RuntimeException | NullPointerException e)
        // {
        // }

        // The exception NullPointerException is already caught by the
        // alternative RuntimeException
        // try
        // {
        // catchManyExceptions.throwIncludeRuntimeException();
        // } catch (NullPointerException | RuntimeException e)
        // {
        // }

        try
        {
            catchManyExceptions.throwIncludeRuntimeException();
        } catch (NullPointerException e)
        {

        } catch (RuntimeException e)
        {

        }

        //      D E  C   , “e”      
        try
        {
            catchManyExceptions.throw2SubExceptions();
        } catch (ExceptionD | ExceptionE e)
        {
            //             
            e.exception_c();
        }
    }
}

class ExceptionA extends Exception
{
}

class ExceptionB extends Exception
{
}

class ExceptionC extends Exception
{
    public void exception_c()
    {
        System.err.println("i'm exception c");
    }
}

//     D     C
class ExceptionD extends ExceptionC
{

}

//       E     C;
class ExceptionE extends ExceptionC
{

}



package com.chap1.exception_optimize;

import java.io.FileInputStream;
import java.io.IOException;

/**
 *         
 * 
 * <pre>
 *     1.                 
 *  2.    ,              ,            
 *  3.                   ,     。                 。
 *  4.Throwable                 ,                    , cause
 *      public Throwable(Throwable cause)
 *  5.                              ,                           。                
 *            
 * </pre>
 * 
 * <output>
 * Exception in thread "main" com.chap1.exception_optimize.DataAccessException: java.io.FileNotFoundException: data.txt (          。)
    at com.chap1.exception_optimize.DataAccessGateway.load(DataAccessGateway.java:34)
    at com.chap1.exception_optimize.DataAccessGateway.main(DataAccessGateway.java:41)
Caused by: java.io.FileNotFoundException: data.txt (          。)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(Unknown Source)
    at java.io.FileInputStream.<init>(Unknown Source)
    at com.chap1.exception_optimize.DataAccessGateway.load(DataAccessGateway.java:30)
     1 more
 * </output>
 * 
 * @author landon
 * @since 1.7.0_51
 * @version 1.0.0 2014 4 23 
 * 
 */

public class DataAccessGateway
{
    public void load() throws DataAccessException
    {
        try
        {
            FileInputStream input = new FileInputStream("data.txt");
        } catch (IOException e)
        {
            //          DataAccessException,     IOException   ,       
            throw new DataAccessException(e);
        }
    }
    
    public static void main(String[] args)
    {
        DataAccessGateway gateway = new DataAccessGateway();
        gateway.load();
    }
}

//       
class DataAccessException extends RuntimeException
{
    public DataAccessException(Throwable cause)
    {
        super(cause);
    }
}
package com.chap1.exception_optimize;

/**
 * 
 *    “  ”,    catch    NumberFormatException(  );  finally      ArithmeticException(  )
 *    :  try      ,                 ,finally        
 * 
 * <output>
 * Exception in thread "main" com.chap1.exception_optimize.BaseException: java.lang.ArithmeticException: / by zero
    at com.chap1.exception_optimize.DisappearException.show(DisappearException.java:30)
    at com.chap1.exception_optimize.DisappearException.main(DisappearException.java:38)
Caused by: java.lang.ArithmeticException: / by zero
    at com.chap1.exception_optimize.DisappearException.show(DisappearException.java:27)
     1 more
 * </output>
 * 
 *        ,    finally    ArithmeticException     , try       “  ” .                ,         ,
 * finally         (      ),         ,                        
 * 
 * @author landon
 * @since 1.7.0_51
 * @version 1.0.0 2014 4 23 
 * 
 */

public class DisappearException
{
    public void show() throws BaseException
    {
        try
        {
            Integer.parseInt("hello");
        } catch (NumberFormatException e)
        {
            throw new BaseException(e);
        } finally
        {
            try
            {
                int result = 2 / 0;
            } catch (ArithmeticException e)
            {
                throw new BaseException(e);
            }
        }
    }
    
    public static void main(String[] args)
    {
        DisappearException disappearException = new DisappearException();
        disappearException.show();
    }
}

class BaseException extends RuntimeException
{
    public BaseException(Throwable cause)
    {
        super(cause);
    }
}


package com.chap1.exception_optimize;

/**
 * 
 *   Throwable#void addSuppressed(Throwable exception)  '  '    
 *               ,    "Suppressed"
 * 
 * <output>
 * Exception in thread "main" com.chap1.exception_optimize.BaseException: java.lang.NumberFormatException: For input string: "hello"
    at com.chap1.exception_optimize.DisappearExceptionResolve.show(DisappearExceptionResolve.java:43)
    at com.chap1.exception_optimize.DisappearExceptionResolve.main(DisappearExceptionResolve.java:51)
Caused by: java.lang.NumberFormatException: For input string: "hello"
    at java.lang.NumberFormatException.forInputString(Unknown Source)
    at java.lang.Integer.parseInt(Unknown Source)
    at java.lang.Integer.parseInt(Unknown Source)
    at com.chap1.exception_optimize.DisappearExceptionResolve.show(DisappearExceptionResolve.java:21)
     1 more
    Suppressed: java.lang.ArithmeticException: / by zero
        at com.chap1.exception_optimize.DisappearExceptionResolve.show(DisappearExceptionResolve.java:29)
         1 more
 * </output>
 * 
 * @author landon
 * @since 1.7.0_51
 * @version 1.0.0 2014 4 23 
 * 
 */

public class DisappearExceptionResolve
{
    public void show() throws BaseException
    {
        Throwable throwable = null;

        try
        {
            Integer.parseInt("hello");
        } catch (NumberFormatException e)
        {
            throwable = e;
        } finally
        {
            try
            {
                int result = 2 / 0;
            } catch (ArithmeticException e)
            {
                if (throwable != null)
                {
                    throwable.addSuppressed(e);
                } else
                {
                    throwable = e;
                }
            }

            if (throwable != null)
            {
                throw new BaseException(throwable);
            }
        }
    }
    
    public static void main(String[] args)
    {
        DisappearExceptionResolve resolve = new DisappearExceptionResolve();
        resolve.show();
    }
}

package com.chap1.exception_optimize;

import java.math.BigDecimal;

/**
 * 
 *       
 * 
 * <pre>
 *     1.native2ascii,  ,            ->\u4f59\u989d\u4e0d\u8db3
 *  2.  message_zh_cn.properties
 * </pre>
 * 
 * <output>
 *     Exception in thread "main" com.chap1.exception_optimize.InsufficientBalanceException:     :8.09:10.32:2.23
    at com.chap1.exception_optimize.InsufficientBalanceException.main(InsufficientBalanceException.java:47)
 * </output>
 * 
 * @author landon
 * @since 1.7.0_51
 * @version 1.0.0 2014 4 23 
 * 
 */

public class InsufficientBalanceException extends LocalizedException
{
    //     
    private BigDecimal requested;
    //   
    private BigDecimal balance;
    //   
    private BigDecimal shortage;
    
    public InsufficientBalanceException(BigDecimal requested,BigDecimal balance)
    {
        super("INSUFFICIENT_BALANCE_EXCEPTION");
        
        this.requested = requested;
        this.balance = balance;
        
        this.shortage = requested.subtract(balance);
    }

    @Override
    public String getLocalizedMessage()
    {
        return format(balance,requested,shortage);
    }

    public static void main(String[] args) throws Exception
    {
        throw new InsufficientBalanceException(new BigDecimal("10.32") , new BigDecimal("8.09"));
    }
}

package com.chap1.exception_optimize;

import java.text.MessageFormat;
import java.util.ResourceBundle;

/**
 * 
 *              ,  ResourceBundle   
 * 
 * <pre>
 *     1.        (properties),    .properties       (     ),             (       ),       properties     。
 *       ,       ,  properties          :        :     _    _    .properties,
 *  2.      ,    :    .properties
 *  3.  :msg_en_US.properties,msg_zh_CN.properties,msg.properties
 *  4.        ISO-8859-1  ->native2ascii  
 *  5.MessageFormat:     
 * </pre>
 * 
 * @author landon
 * @since 1.7.0_51
 * @version 1.0.0 2014 4 23 
 * 
 */

public abstract class LocalizedException extends Exception
{
    private String messageKey;
    protected ResourceBundle resourceBundle;

    public LocalizedException(String msgKey)
    {
        messageKey = msgKey;
        initResouceBundle();
    }

    public abstract String getLocalizedMessage();

    //      
    @Override
    public String getMessage()
    {
        return getLocalizedMessage();
    }

    private void initResouceBundle()
    {
        resourceBundle = ResourceBundle.getBundle("message_zh_CN");
    }

    protected String format(Object args)
    {
        String message = resourceBundle.getString(messageKey);
        return MessageFormat.format(message, args);
    }
}

package com.chap1.exception_optimize;

/**
 * 
 *         Java7 ,    catch           catch         ,
 *                                try          ,          catch       
 * 
 * @author landon
 * @since 1.7.0_51
 * @version 1.0.0 2014 4 28 
 * 
 */

public class PreciseThrowUse
{
    public void testThrow() throws ExceptionA
    {
        try
        {
            throw new ExceptionASub2();
        } catch (ExceptionA e)
        {
            //       :               ExceptionASub2,   catchExceptionASub1     
            // Java6             :1.   try           catch     ExceptionA,     catch   (  )
            //   ExceptionA    ExceptionASub1    .
            // try
            // {
            // throw e;
            // }
            // catch(ExceptionASub1 e2)
            // {
            //
            // }

            //           ,  e       ExceptionASub2
            // try
            // {
            // throw e;
            // } catch (ExceptionASub2 e2)
            // {
            //
            // }
            
            //          ,  e   ExceptionA  
            try
            {
                throw e;
            } catch (ExceptionA e3)
            {

            }
        }
    }
}

// ExceptionA      1
class ExceptionASub1 extends ExceptionA
{

}

// ExceptionA      2
class ExceptionASub2 extends ExceptionA
{

}

package com.chap1.exception_optimize;

import java.io.FileInputStream;
import java.io.IOException;

/**
 * 
 *   "    ",         :        , Java7  Throwable    addSuppressed  .    
 *         ,       
 *           ,              addSuppressed               。                    
 * ,     getSuppressed          。               ,          。
 *     Throwable     1.7      
 * 
 * <pre>
 *      * @serial
 * @since 1.7
 * 
 *      private List<Throwable> suppressedExceptions = SUPPRESSED_SENTINEL;
 * </pre>
 * 
 * @author landon
 * @since 1.7.0_51
 * @version 1.0.0 2014 4 23 
 * 
 */

public class ReadFileAddSuppressedException
{
    //  finally         addSuppressed     try        
    public void read(String fileName) throws BaseException
    {
        FileInputStream input = null;
        IOException ioException = null;

        try
        {
            input = new FileInputStream(fileName);
        } catch (IOException e)
        {
            ioException = e;
        } finally
        {
            if (input != null)
            {
                try
                {
                    input.close();
                } catch (IOException e)
                {
                    if (ioException != null)
                    {
                        //   “suppressedExceptions”
                        ioException.addSuppressed(e);
                    } else
                    {
                        ioException = e;
                    }
                }
            }

            if (ioException != null)
            {
                throw new BaseException(ioException);
            }
        }
    }
}

package com.chap1.exception_optimize;

import java.io.FileInputStream;
import java.io.IOException;

/**
 *
 *   "    ",         :
 * 1.  try         ,   finally      ,     try             
 *
 * @author landon
 * @since 1.7.0_51
 * @version 1.0.0 2014 4 23 
 *
 */

public class ReadFileIgnoreFinallyException
{
    public void read(String fileName) throws BaseException
    {
        FileInputStream input = null;
        IOException ioException = null;
        
        try
        {
            input = new FileInputStream(fileName);
        }
        catch(IOException e)
        {
            ioException = e;
        }
        finally
        {
            if(input != null)
            {
                try
                {
                    input.close();
                }
                catch(IOException e)
                {
                    if(ioException == null)
                    {
                        ioException = e;
                    }
                }
            }
            
            if(ioException != null)
            {
                throw new BaseException(ioException);
            }
        }
    }
}

 INSUFFICIENT_BALANCE_EXCEPTION = insufficient balance:{0}:{1}:{2}

 INSUFFICIENT_BALANCE_EXCEPTION = \u4f59\u989d\u4e0d\u8db3\uFF1A{0}\uFF1A{1}\uFF1A{2}

4.try-with-resources  

package com.chap1.try_resources;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * 
 * 1.1.7   try            , try-with-resources  
 * 2.    :   ,   (   ,    ,    ,      )->    ,          ,          
 * 3.1.7    try-catch-finall     finally          ,      ,        
 * 4.1.7 try       ,           ,           
 * 5.        ,       try               ,     , try         ;        ,     try   ,
 *                          Throwable#addSuppressed    
 * 
 * @author landon
 * @since 1.7.0_51
 * @version 1.0.0 2014 4 28 
 * 
 */

public class ResourceBasicUse
{
    public String readFile(String path) throws IOException
    {
        // try()
        //          finally              ,       。     finally   ,    
        try (BufferedReader reader = new BufferedReader(new FileReader(path)))
        {
            StringBuilder builder = new StringBuilder();

            String line = null;
            while ((line = reader.readLine()) != null)
            {
                builder.append(line);
                //    
                builder.append(String.format("%n"));
            }

            return builder.toString();
        }
    }
    
    public static void main(String[] args) throws Exception
    {
        ResourceBasicUse basicUse = new ResourceBasicUse();
        basicUse.readFile("tmp.txt");
    }
}
package com.chap1.try_resources;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * 
 * try-with-resources           
 * 1.             ,             ;                    try                 
 * 2.try-with-resources       catch finally  。 catch       try                  
 * 
 * @author landon
 * @since 1.7.0_51
 * @version 1.0.0 2014 4 28 
 * 
 */

public class MultiResourceUse
{
    //         
    public void copyFile(String fromPath, String toPath) throws IOException
    {
        //            ,     input output
        try (InputStream input = new FileInputStream(fromPath);
                OutputStream output = new FileOutputStream(toPath))
        {
            byte[] bytes = new byte[8192];
            int len = -1;

            while ((len = input.read(bytes)) != -1)
            {
                output.write(bytes, 0, len);
            }
        }
        //   catch
        catch (Exception e)
        {
            e.printStackTrace();
        }
        //   finally
        finally
        {
            System.out.println("copy file.finally");
        }
    }

    public static void main(String[] args) throws Exception
    {
        MultiResourceUse mru = new MultiResourceUse();
        mru.copyFile("source.txt", "dest.txt");
    }
}

package com.chap1.try_resources;

/**
 *         1. try               : Java    AutoCloseable  .         .         ,
 *     close        . 2.Java                      。->   IO           .
 *  :java.io.Closeable extends AutoCloseable ;java.sql.Connection extends
 * Wrapper, AutoCloseable
 * 3.            try          ,     AutoCloseable   close    .
 * 
 * @author landon
 * @since 1.7.0_51
 * @version 1.0.0 2014 4 28 
 * 
 */

public class CustomResource implements AutoCloseable
{

    @Override
    public void close() throws Exception
    {
        System.out.println("      ");
    }

    public void useCustomResource() throws Exception
    {
        try (CustomResource resource = new CustomResource())
        {
            System.out.println("    ");
        }
    }

    public static void main(String[] args) throws Exception
    {
        // Resource leak: 'cr' is never closed
        CustomResource cr = new CustomResource();
        //       
        //       
        //        :close          
        cr.useCustomResource();
    }

}

5.           

package com.chap1.varargs_optimize;

import java.util.ArrayList;

/**
 * 
 *         1.Java7  ,                   :          , useVarargs  
 *       ,Java7         
 * :@SafeVarargs,                                      ,              。
 *  :                               static  final 
 * (landon:why:               ?                 ),         . useVarargs3
 *                                              
 * 
 * <pre>
 * @Documented
 * @Retention(RetentionPolicy.RUNTIME)
 * @Target({ ElementType.CONSTRUCTOR, ElementType.METHOD })
 * public @interface SafeVarargs
 * {
 * }
 * </pre>
 * 
 * @author landon
 * @since 1.7.0_51
 * @version 1.0.0 2014 4 28 
 * 
 */

public class VarargsOptimize
{
    //                 , List<String>     ,       .                        
    //                   ,          .
    //   Arrays.asList/Collections.addAll  
    public static <T> T useVarargs(T args)
    {
        return args.length > 0 ? args[0] : null;
    }

    //       
    @SafeVarargs
    public static <T> T useVarargs2(T args)
    {
        return args.length > 0 ? args[0] : null;
    }

    //     :@SafeVarargs annotation cannot be applied to non-final instance
    // method useVarargs3,    final  
    // @SafeVarargs
    // public <T> T useVarargs3(T args)
    // {
    // return args.length > 0 ? args[0] : null;
    // }
    
    //     ,   final         :    :              ,                 .
    @SafeVarargs
     public final <T> T useVarargs4(T args)
     {
     return args.length > 0 ? args[0] : null;
     }

    public static void main(String[] args)
    {
        //   :Type safety: A generic array of ArrayList<String> is created for a
        // varargs parameter
        useVarargs(new ArrayList<String>());

        //       ,     @SafeVarargs  
        useVarargs2(new ArrayList<String>());
    }
}