After reading Effective Java, I feel that it is written quite well. Most of the middle is used as a reference manual, so I sort it out. Combined with the framework source code, JDK source code, their own demo, to give you more examples, easy to understand. Each introduction is for personal understanding, if there is any wrong, hope to point out. I would also like to give any suggestions for blogs.

5.Give priority to dependency injection to reference resources

Dependency injection: Passing a dependent resource to an instance object through a constructor. Those of you who have used Spring already know the benefits, but

  • example
public interface Computer {
    public void program(a);
}

class WindowsComputer implements Computer{
    @Override
    public void program(a) {
        System.out.println("windows"); }}class MacComputer implements Computer{
    @Override
    public void program(a) {
        System.out.println("Mac"); }}Copy the code
/** * dependency injection: when creating an instance, pass the instance ** / through the constructor
public class DependencyDemo {
    private Computer computer;
    public DependencyDemo(Computer computer){
        this.computer=computer;
    }


    public void function(a){ computer.program(); }}Copy the code

6.Avoid creating unnecessary objects

It is best to reuse a single object instead of creating a new object every time you need it. String s=new String(“demo”); This example is given in the text. This creates an extra object for no reason. Instead, String s=”demo”; Static factory methods should be used in preference to constructors to avoid creating unnecessary objects. Things like integer.valueof -128 to 127 are reused, and if constructors are used, new objects are created one at a time

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}
Copy the code
public Integer(int value) {
    this.value = value;
}
Copy the code

Also avoid auto-boxing and use primitive data types in preference to primitive data types. As in the example below, there is a 6-fold difference between primitive data types and corresponding objects, but calculations used in real development are still rare. Some numeric type calculations are also commonly used in BigDecimal, but be careful when used.

private static void autoboxing(a) {
    //13ms
    Integer i=1;
    //2ms
    //int i=1;
    long start=System.currentTimeMillis();
    for (int j = 0; j < 1000000; j++) {
        i+=1;
    }
    long end=System.currentTimeMillis();
    System.out.println(end-start);
}
Copy the code

7.Eliminate expired object references

In the example given in the book, elements still refers to the object returned from the pop method in the Stack. However, in the eyes of other callers, it should not exist, there will be OOM in the future.

public class Stack {
    private Object[] elements;
    private int size = 0;
    private static final int DEFAULT_INITIAL_CAPACITY = 16;
    
    public Stack(a){
        elements = new Object[DEFAULT_INITIAL_CAPACITY];
    }
    
    public void push(Object e){
        ensureCapacity();
        elements[size ++] = e;
    }
    
    public Object pop(a){
        if (size == 0) {throw new EmptyStackException();
        }
        return elements[--size];
    }
    
    private void ensureCapacity(a){
        if (elements.length == size){
            elements = Arrays.copyOf(elements, 2 * size + 1); }}}Copy the code

There is a concept mentioned in the book. An expired reference, a reference that can never be removed again. Back to business, but in daily development, this should be avoided. It should be changed to so that the GC does the collection. The root-reachable algorithm, since there is no reference to point to, will recycle

    public Object pop(a){
        if (size == 0) {throw new EmptyStackException();
        }
        Object o=elements[--size];
        elements[size] =null;
        return o
    }
Copy the code

But even this is still possible OOM, for example, is some scenes, will occupy a large number of references do not put, this scene is also to be careful. In addition, the article advocates the use of WeakHashMap, which is a weak reference in which the presence of a key does not prevent values from being discarded. (I haven’t used it yet, so check back)

8.Avoid finalization and cleanup methods

This basically means avoiding finalizers (java9 obsolete) and cleaner (Java9). Finalizers (java9 obsolete) and Cleaner (Java9), because these two methods are unpredictable (there is no guarantee that they will be executed) and run slowly. Even calls to System.gc and system. runFinalization are not guaranteed to be executed. If you need to ensure that some resources terminate (input/output streams), you generally use try-catch-finally, or implement AutoCloseable using try-with-resources. I can’t find any suitable examples for this part, and I won’t sort out the examples if I don’t use them often.

9.The try – with – resources priority try-catch – finally

Try-catch hell – finally, the most typical is the input and output flow, try to recall the written inside the school, the most primitive, can also be in the middle of the try-catch omit, wrote of the close together, write a small script basic no problem, but before again with code detection software will be to violations. Here is also an example that is now written, the basic actual development or to find a tool class. Because a close can also fail, it’s a try-catch.

public static void main(String[] args)  {
    File fileInput = new File("/Users/chenhui/Downloads/aa.txt");
    String path="/Users/chenhui/Downloads/testtttt";
    String name="bb.txt";
    File pathFile = new File(path);
    if(! pathFile.exists()){ pathFile.mkdirs(); } String relFilePath = path + File.separator + name; File fileOutput =new File(relFilePath);
    if(! fileOutput.exists()) {try {
            fileOutput.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    FileInputStream fileInputStream=null;
    FileOutputStream fileOutputStream=null;
    try {
        fileInputStream = new FileInputStream(fileInput);
        try{
             fileOutputStream = new FileOutputStream(fileOutput);
            byte[] b = new byte[1024];
            int len;
            while((len = fileInputStream.read(b)) ! = -1){
                fileOutputStream.write(b,0,len); }}catch (Exception e) {
            e.printStackTrace();
        }finally {
            // When output is complete, close the output streamfileOutputStream.close(); }}catch (Exception e) {
        e.printStackTrace();
    }finally {

        try {
            // The null pointer is abnormal
            fileInputStream.close();
        } catch(IOException e) { e.printStackTrace(); }}}Copy the code

If implemented using java7’s try-resource.

private static void extra2(a) {
    File fileInput = new File("/Users/chenhui/Downloads/aa.txt");
    String path="/Users/chenhui/Downloads/testtttt";
    String name="bb.txt";
    File pathFile = new File(path);
    if(! pathFile.exists()){ pathFile.mkdirs(); } String relFilePath = path + File.separator + name; File fileOutput =new File(relFilePath);
    if(! fileOutput.exists()) {try {
            fileOutput.createNewFile();
        } catch(IOException e) { e.printStackTrace(); }}try(FileInputStream fileInputStream= new FileInputStream(fileInput);
        FileOutputStream fileOutputStream= newFileOutputStream(fileOutput); ) {byte[] b = new byte[1024];
        int len;
        while((len = fileInputStream.read(b)) ! = -1){
            fileOutputStream.write(b,0,len); }}catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch(IOException e) { e.printStackTrace(); }}Copy the code

The implementation of Closeable will automatically close the stream for us, which is very convenient to use. If you decomcompile it, you can see that this is a syntax candy, and there may be many problems with closing the stream

private static void extra2(a) {
    File var0 = new File("/Users/chenhui/Downloads/aa.txt");
    String var1 = "/Users/chenhui/Downloads/testtttt";
    String var2 = "bb.txt";
    File var3 = new File(var1);
    if(! var3.exists()) { var3.mkdirs(); } String var4 = var1 + File.separator + var2; File var5 =new File(var4);
    if(! var5.exists()) {try {
            var5.createNewFile();
        } catch(IOException var39) { var39.printStackTrace(); }}try {
        FileInputStream var6 = new FileInputStream(var0);
        Throwable var7 = null;

        try {
            FileOutputStream var8 = new FileOutputStream(var5);
            Throwable var9 = null;

            try {
                byte[] var10 = new byte[1024];

                int var11;
                while((var11 = var6.read(var10)) ! = -1) {
                    var8.write(var10, 0, var11); }}catch (Throwable var40) {
                var9 = var40;
                throw var40;
            } finally {
                if(var8 ! =null) {
                    if(var9 ! =null) {
                        try {
                            var8.close();
                        } catch(Throwable var38) { var9.addSuppressed(var38); }}else{ var8.close(); }}}}catch (Throwable var42) {
            var7 = var42;
            throw var42;
        } finally {
            if(var6 ! =null) {
                if(var7 ! =null) {
                    try {
                        var6.close();
                    } catch(Throwable var37) { var7.addSuppressed(var37); }}else{ var6.close(); }}}}catch (FileNotFoundException var44) {
        var44.printStackTrace();
    } catch(IOException var45) { var45.printStackTrace(); }}Copy the code

But try-catch – finally besides flow is very common for chestnut Mybatis org. Apache. Ibatis. Session. SqlSessionManager. SqlSessionInterceptor catch exceptions method calls, Mybatis is also useful in other places (too long time did not see, a little forgotten), such as SQL execution if there is a problem, to ensure that the connection is closed, finally can define their own or very cool, (dare also can be the whole try live, ensure not throw exceptions 🐶).

private class SqlSessionInterceptor implements InvocationHandler {
    private SqlSessionInterceptor(a) {}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        SqlSession sqlSession = (SqlSession)SqlSessionManager.this.localSqlSession.get();
        if(sqlSession ! =null) {
            try {
                return method.invoke(sqlSession, args);
            } catch (Throwable var12) {
                throwExceptionUtil.unwrapThrowable(var12); }}else {
            SqlSession autoSqlSession = SqlSessionManager.this.openSession();

            Object var7;
            try {
                Object result = method.invoke(autoSqlSession, args);
                autoSqlSession.commit();
                var7 = result;
            } catch (Throwable var13) {
                autoSqlSession.rollback();
                throw ExceptionUtil.unwrapThrowable(var13);
            } finally {
                autoSqlSession.close();
            }

            returnvar7; }}}Copy the code

  • Past the link
    • 1 to 4: juejin.cn/post/698594…