30 Java Programming Tips and Best Practices for Beginners

<span style="color: rgb(51, 51, 51); font-family: Helvetica; font-size: 30px; line-height: 1em; background-color: rgb(255, 255, 255);">1. Prefer returning Empty Collections instead of Null</span>

If a program is returning a collection which does not have any value, make sure an Empty collection is returned rather than Null elements. This saves a lot of “if else” testing on Null Elements.

public class getLocationName {
	return (null==cityName ? "": cityName);
}

2. Use Strings carefully

If two Strings are concatenated using “+” operator in a “for” loop, then it creates a new String Object, every time. This causes wastage of memory and increases performance time. Also, while instantiating a String Object, constructors should be avoided and instantiation should happen directly. For example:

//Slower Instantiation
String bad = new String("Yet another string object");
	 
//Faster Instantiation
String good = "Yet another string object"

3. Avoid unnecessary Objects

One of the most expensive operations (in terms of Memory Utilization) in Java is Object Creation. Thus it is recommended that Objects should only be created or initialized if necessary. Following code gives an example:

import java.util.ArrayList;
import java.util.List;

public class Employees {

	private List Employees;

	public List getEmployees() {

		//initialize only when required
		if(null == Employees) {
			Employees = new ArrayList();
		}
		return Employees;
	}
}

4. Dilemma between Array and ArrayList

Developers often find it difficult to decide if they should go for Array type data structure of ArrayList type. They both have their strengths and weaknesses. The choice really depends on the requirements.

import java.util.ArrayList;

public class arrayVsArrayList {

	public static void main(String[] args) {
		int[] myArray = new int[6];
		myArray[7]= 10; // ArraysOutOfBoundException

		//Declaration of ArrayList. Add and Remove of elements is easy.
		ArrayList<Integer> myArrayList = new ArrayList<>();
		myArrayList.add(1);
		myArrayList.add(2);
		myArrayList.add(3);
		myArrayList.add(4);
		myArrayList.add(5);
		myArrayList.remove(0);
		
		for(int i = 0; i < myArrayList.size(); i++) {
		System.out.println("Element: " + myArrayList.get(i));
		}
		
		//Multi-dimensional Array 
		int[][][] multiArray = new int [3][3][3]; 
	}
}

  1. Arrays have fixed size but ArrayLists have variable sizes. Since the size of Array is fixed, the memory gets allocated at the time of declaration of Array type variable. Hence, Arrays are very fast. On the other hand, if we are not aware of the size of the data, then ArrayList is More data will lead to ArrayOutOfBoundException and less data will cause wastage of storage space.
  2. It is much easier to Add or Remove elements from ArrayList than Array
  3. Array can be multi-dimensional but ArrayList can be only one dimension.

5. When Finally does not get executed with Try

Consider following code snippet:

public class shutDownHooksDemo {
	public static void main(String[] args) {
		for(int i=0;i<5;i++)
		{
			try {
				if(i==4) {
					System.out.println("Inside Try Block.Exiting without executing Finally block.");
					System.exit(0);
				}
			}
			finally {
				System.out.println("Inside Finally Block.");
			}
		}
	}
}

From the program, it looks like “println” inside finally block will be executed 5 times. But if the program is executed, the user will find that finally block is called only 4 times. In the fifth iteration, exit function is called and finally never gets called the fifth time. The reason is- System.exit halts execution of all the running threads including the current one. Even finally block does not get executed after try when exit is executed.

When System.exit is called, JVM performs two cleanup tasks before shut down:

First, it executes all the shutdown hooks which have been registered with Runtime.addShutdownHook. This is very useful because it releases the resources external to JVM.

Second is related to Finalizers. Either System.runFinalizersOnExit or Runtime.runFinalizersOnExit. The use of finalizers has been deprecated from a long time. Finalizers can run on live objects while they are being manipulated by other threads.This results in undesirable results or even in a deadlock.

public class shutDownHooksDemo {

    public static void main(String[] args) {
            for(int i=0;i<5;i++)
            {
                    final int final_i = i;
                    try {
                            Runtime.getRuntime().addShutdownHook(
                                            new Thread() {
                                            public void run() {
                                            if(final_i==4) {
                                            System.out.println("Inside Try Block.Exiting without executing Finally block.");
                                            System.exit(0);
                                            }
                                            }
                                            });
                    }
                    finally {
                            System.out.println("Inside Finally Block.");
                    }

            }
    }
}

6. Check Oddity

Have a look at the lines of code below and determine if they can be used to precisely identify if a given number is Odd?

public boolean oddOrNot(int num) {
	return num % 2 == 1;
}

These lines seem correct but they will return incorrect results one of every four times (Statistically speaking). Consider a negative Odd number, the remainder of division with 2 will not be 1. So, the returned result will be false which is incorrect!

This can be fixed as follows:

public boolean oddOrNot(int num) {
	return (num & 1) != 0;
}
Using this code, not only is the problem of negative odd numbers solved, but this code is also highly optimized. Since, Arithmetic and Logical operations are much faster compared to division and multiplication, the results are achieved faster so in second snippet.

7. Difference between single quotes and double quotes

public class Haha {
	public static void main(String args[]) {
	System.out.print("H" + "a");
	System.out.print('H' + 'a');
	}
}


From the code, it would seem return “HaHa” is returned, but it actually returns Ha169. The reason is that if double quotes are used, the characters are treated as a string but in case of single quotes, the char -valued operands ( ‘H’ and ‘a’ ) to int values through a process known as widening primitive conversion. After integer conversion, the numbers are added and return 169.

8. Avoiding Memory leaks by simple tricks

Memory leaks often cause performance degradation of software. Since, Java manages memory automatically, the developers do not have much control. But there are still some standard practices which can be used to protect from memory leakages.

  • Always release database connections when querying is complete.
  • Try to use Finally block as often possible.
  • Release instances stored in Static Tables.

9. Avoiding Deadlocks in Java

Deadlocks can occur for many different reasons. There is no single recipe to avoid deadlocks. Normally deadlocks occur when one synchronized object is waiting for lock on resources locked by another synchronized object.

Try running the below program. This program demonstrates a Deadlock. This deadlock arises because both the threads are waiting for the resources which are grabbed by other thread. They both keep waiting and no one releases.

public class DeadlockDemo {
   public static Object addLock = new Object();
   public static Object subLock = new Object();

   public static void main(String args[]) {

      MyAdditionThread add = new MyAdditionThread();
      MySubtractionThread sub = new MySubtractionThread();
      add.start();
      sub.start();
   }
private static class MyAdditionThread extends Thread {
      public void run() {
         synchronized (addLock) {
		int a = 10, b = 3;
		int c = a + b;
            System.out.println("Addition Thread: " + c);
            System.out.println("Holding First Lock...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Addition Thread: Waiting for AddLock...");
            synchronized (subLock) {
               System.out.println("Threads: Holding Add and Sub Locks...");
            }
         }
      }
   }
   private static class MySubtractionThread extends Thread {
      public void run() {
         synchronized (subLock) {
		int a = 10, b = 3;
		int c = a - b;
            System.out.println("Subtraction Thread: " + c);
            System.out.println("Holding Second Lock...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Subtraction  Thread: Waiting for SubLock...");
            synchronized (addLock) {
               System.out.println("Threads: Holding Add and Sub Locks...");
            }
         }
      }
   }
}

Output:
=====
Addition Thread: 13
Subtraction Thread: 7
Holding First Lock...
Holding Second Lock...
Addition Thread: Waiting for AddLock...
Subtraction  Thread: Waiting for SubLock...
But if the order in which the threads are called is changed, the deadlock problem is resolved.
public class DeadlockSolutionDemo {
   public static Object addLock = new Object();
   public static Object subLock = new Object();

   public static void main(String args[]) {

      MyAdditionThread add = new MyAdditionThread();
      MySubtractionThread sub = new MySubtractionThread();
      add.start();
      sub.start();
   }


private static class MyAdditionThread extends Thread {
      public void run() {
         synchronized (addLock) {
		int a = 10, b = 3;
		int c = a + b;
            System.out.println("Addition Thread: " + c);
            System.out.println("Holding First Lock...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Addition Thread: Waiting for AddLock...");
            synchronized (subLock) {
               System.out.println("Threads: Holding Add and Sub Locks...");
            }
         }
      }
   }
   
   private static class MySubtractionThread extends Thread {
      public void run() {
         synchronized (addLock) {
		int a = 10, b = 3;
		int c = a - b;
            System.out.println("Subtraction Thread: " + c);
            System.out.println("Holding Second Lock...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Subtraction  Thread: Waiting for SubLock...");
            synchronized (subLock) {
               System.out.println("Threads: Holding Add and Sub Locks...");
            }
         }
      }
   }
}
Output:
=====
Addition Thread: 13
Holding First Lock...
Addition Thread: Waiting for AddLock...
Threads: Holding Add and Sub Locks...
Subtraction Thread: 7
Holding Second Lock...
Subtraction  Thread: Waiting for SubLock...
Threads: Holding Add and Sub Locks...
<span style="font-family: Helvetica; font-size: 30px; line-height: 1em; background-color: rgb(255, 255, 255);">10. Reserve memory for Java</span>

Some of the Java applications can be highly CPU intensive as well as they need a lot of RAM. Such applications generally run slow because of a high RAM requirement. In order to improve performance of such applications, RAM is reserved for Java. So, for example, if we have a Tomcat webserver and it has 10 GB of RAM. If we like, we can allocate RAM for Java on this machine using the following command:

export JAVA_OPTS="$JAVA_OPTS -Xms5000m -Xmx6000m -XX:PermSize=1024m -XX:MaxPermSize=2048m"

  • Xms = Minimum memory allocation pool
  • Xmx = Maximum memory allocation pool
  • XX:PermSize = Initial size that will be allocated during startup of the JVM
  • XX:MaxPermSize = Maximum size that can be allocated during startup of the JVM

11. How to time operations in Java

There are two standard ways to time operations in Java: System.currentTimeMillis() and System.nanoTime() The question is, which of these to choose and under what circumstances. In principle, they both perform the same action but are different in the following ways:

  1. System.currentTimeMillis takes somewhere between 1/1000th of a second to 15/1000th of a second (depending on the system) but System.nanoTime() takes around 1/1000,000th of a second (1,000 nanos)
  2. System.currentTimeMillis takes a few clock cycles to perform Read Operation. On the other hand, System.nanoTime() takes 100+ clock cycles.
  3. System.currentTimeMillis reflects Absolute Time (Number of millis since 1 Jan 1970 00:00 (Epoch Time)) but System.nanoTime() does not necessarily represent any reference point.

12. Choice between Float and Double

Data type Bytes used Significant figures (decimal)
Float 4 7
Double 8 15

Double is often preferred over float in software where precision is important because of the following reasons:

Most processors take nearly the same amount of processing time to perform operations on Float and Double. Double offers far more precision in the same amount of computation time.






1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 、 1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READmE.文件(md如有),本项目仅用作交流学习参考,请切勿用于商业用途。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值