Common Java Coding Pitfalls and Best‑Practice Alternatives
This article presents a collection of common Java coding pitfalls—such as using 'where 1=1' in MyBatis, inefficient Map iteration, improper collection checks, and suboptimal string handling—and provides concise, performance‑oriented best‑practice alternatives with code examples.
Avoid "where 1=1" for Multiple MyBatis Query Conditions
Using where 1=1 may force a full table scan, preventing index usage and causing performance loss as well as potential SQL‑injection risk.
Bad example:
<select id="queryBookInfo" parameterType="com.tjt.platform.entity.BookInfo" resultType="java.lang.Integer">
select count(*) from t_rule_BookInfo t where 1=1
<if test="title !=null and title !='' "> AND title = #{title} </if>
<if test="author !=null and author !='' "> AND author = #{author} </if>
</select>Good example:
<select id="queryBookInfo" parameterType="com.tjt.platform.entity.BookInfo" resultType="java.lang.Integer">
select count(*) from t_rule_BookInfo t
<where>
<if test="title !=null and title !='' "> title = #{title} </if>
<if test="author !=null and author !='' "> AND author = #{author} </if>
</where>
</select>Iterate entrySet() to Get Map Keys and Values
When both key and value are needed, iterating entrySet() is more efficient than iterating keySet() and calling get() for each key.
Bad example:
// Map get value bad example
HashMap<String, String> map = new HashMap<>();
for (String key : map.keySet()) {
String value = map.get(key);
}Good example:
// Map get key & value good example
HashMap<String, String> map = new HashMap<>();
for (Map.Entry<String,String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
}Use Collection.isEmpty() to Check Emptiness
isEmpty()is O(1) and makes the intent clearer than checking size()==0, which may be O(n) for some collections.
Bad example:
LinkedList<Object> collection = new LinkedList<>();
if (collection.size() == 0) {
System.out.println("collection is empty.");
}Good example:
LinkedList<Object> collection = new LinkedList<>();
if (collection.isEmpty()) {
System.out.println("collection is empty.");
}
// null‑check can also use CollectionUtils.isEmpty()
if (CollectionUtils.isEmpty(collection)) {
System.out.println("collection is null.");
}Specify Collection Size When Initializing
Providing an initial capacity reduces the number of costly resize operations (typically O(n)).
Bad example:
// List init bad example
int[] arr = new int[]{1,2,3,4};
List<Integer> list = new ArrayList<>();
for (int i : arr) {
list.add(i);
}Good example:
// List init good example
int[] arr = new int[]{1,2,3,4};
List<Integer> list = new ArrayList<>(arr.length);
for (int i : arr) {
list.add(i);
}Use StringBuilder for String Concatenation in Loops
In loops the compiler cannot optimise plain += concatenation, so StringBuilder should be used.
Bad example:
// Loop concatenation bad example
String str = "";
for (int i = 0; i < 10; i++) {
// Java will not optimise this
str += i;
}Good example:
// Loop concatenation good example
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++) {
sb.append(i);
}Use Set for Frequent contains() Checks
List contains() is O(n); converting the list to a HashSet makes the operation O(1).
Bad example:
// Frequent contains bad example
List<Object> list = new ArrayList<>();
for (int i = 0; i <= Integer.MAX_VALUE; i++) {
if (list.contains(i)) {
System.out.println("list contains " + i);
}
}Good example:
// Frequent contains good example
List<Object> list = new ArrayList<>();
Set<Object> set = new HashSet<>();
for (int i = 0; i <= Integer.MAX_VALUE; i++) {
if (set.contains(i)) {
System.out.println("list contains " + i);
}
}Initialize Static Members with Static Blocks
Static collections should be populated inside a static initializer rather than using an anonymous subclass.
Bad example:
private static Map<String, Integer> map = new HashMap<String, Integer>(){{
map.put("Leo",1);
map.put("Family-loving",2);
map.put("Cold on the outside passionate on the inside",3);
}};
private static List<String> list = new ArrayList<>(){{
list.add("Sagittarius");
list.add("Charming");
list.add("Perfectionist");
}};Good example:
private static Map<String, Integer> map = new HashMap<String, Integer>();
static {
map.put("Leo",1);
map.put("Family-loving",2);
map.put("Cold on the outside passionate on the inside",3);
}
private static List<String> list = new ArrayList<>();
static {
list.add("Sagittarius");
list.add("Charming");
list.add("Perfectionist");
}Hide Constructor in Utility Classes
Utility classes should have a private constructor to prevent accidental instantiation.
Bad example:
public class PasswordUtils {
private static final Logger LOG = LoggerFactory.getLogger(PasswordUtils.class);
public static final String DEFAULT_CRYPT_ALGO = "PBEWithMD5AndDES";
public static String encryptPassword(String aPassword) throws IOException {
return new PasswordUtils(aPassword).encrypt();
}
}Good example:
public class PasswordUtils {
private static final Logger LOG = LoggerFactory.getLogger(PasswordUtils.class);
private PasswordUtils() {} // hide implicit public constructor
public static final String DEFAULT_CRYPT_ALGO = "PBEWithMD5AndDES";
public static String encryptPassword(String aPassword) throws IOException {
return new PasswordUtils(aPassword).encrypt();
}
}Remove Redundant Exception Catching and Rethrow
If a catch block only rethrows the exception, it can be omitted.
Bad example:
private static String fileReader(String fileName) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String line;
StringBuilder builder = new StringBuilder();
while ((line = reader.readLine()) != null) {
builder.append(line);
}
return builder.toString();
} catch (Exception e) {
// just rethrow
throw e;
}
}Good example:
private static String fileReader(String fileName) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String line;
StringBuilder builder = new StringBuilder();
while ((line = reader.readLine()) != null) {
builder.append(line);
}
return builder.toString();
// removed redundant catch block
}
}Prefer String.valueOf() Over Concatenation
Converting values to strings with String.valueOf() is more efficient than using "" + value.
Bad example:
int num = 520;
String strLove = "" + num;Good example:
int num = 520;
String strLove = String.valueOf(num);Avoid BigDecimal(double) Constructor
Using the BigDecimal(double) constructor can introduce precision loss; use BigDecimal.valueOf(double) instead.
Bad example: BigDecimal bigDecimal = new BigDecimal(0.11D); Good example:
BigDecimal bigDecimal1 = BigDecimal.valueOf(0.11D);Return Empty Arrays or Collections Instead of null
Returning empty structures avoids NullPointerExceptions and eliminates the need for callers to perform null checks.
Bad example:
public static Result[] getResults() { return null; }
public static List<Result> getResultList() { return null; }
public static Map<String, Result> getResultMap() { return null; }Good example:
public static Result[] getResults() { return new Result[0]; }
public static List<Result> getResultList() { return Collections.emptyList(); }
public static Map<String, Result> getResultMap() { return Collections.emptyMap(); }Call equals() on Constant or Known Non‑null Value
Calling equals() on a constant prevents possible NullPointerExceptions.
Bad example: return fileName.equals("Charming"); Good example:
return "Charming".equals(fileName);
// or Objects.equals("Charming", fileName)Enum Fields Should Be Private and Immutable
Enum attributes must be private, final, and set only via the constructor; no setters should be provided.
Bad example:
public enum SwitchStatus {
DISABLED(0, "禁用"),
ENABLED(1, "启用");
public int value;
private String description;
public void setDescription(String description) { this.description = description; }
}Good example:
public enum SwitchStatus {
DISABLED(0, "禁用"),
ENABLED(1, "启用");
private final int value;
private final String description;
private SwitchStatus(int value, String description) {
this.value = value;
this.description = description;
}
public int getValue() { return value; }
public String getDescription() { return description; }
}Escape Regex Metacharacters in String.split()
Since the argument to split() is a regular expression, characters like . and | must be escaped.
Bad example:
String[] split = "a.ab.abc".split(".");
String[] split1 = "a|ab|abc".split("|");Good example:
String[] split2 = "a.ab.abc".split("\\.");
String[] split3 = "a|ab|abc".split("\\|");Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Captain
Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
