Backend Development 10 min read

10 Java 17 Best Practices for Cleaner, Safer Code

This article presents ten practical Java 17 tips—ranging from using Optional and String.valueOf() to leveraging Arrays.copyOf, isEmpty(), pre‑compiled regex, and generics—to avoid common pitfalls, improve performance, and write more readable and robust backend code.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
10 Java 17 Best Practices for Cleaner, Safer Code

1. Nulls and Optionals

Bad example: Returning null from a method can cause a NullPointerException.

<code>public String getValue() {
  // TODO
  return null;
}</code>

Good example: Use Optional to handle possible absence of a value explicitly.

<code>public Optional<String> getValue() {
  // TODO
  return Optional.empty();
}</code>

2. Use String.valueOf() for String conversion

Bad example: Concatenating with the + operator performs implicit conversion and can be inefficient.

<code>double pi = 3.1415926;
String str = "" + pi;</code>

Good example: Use the dedicated conversion method.

<code>double pi = 3.1415926;
String str = String.valueOf(pi);</code>

3. Use Arrays.copyOf() to copy arrays

Bad example: Manually copying each element with a loop.

<code>int[] source = {1, 2, 3, 4, 5};
int[] target = new int[source.length];
for (int i = 0, len = source.length; i < len; i++) {
  target[i] = source[i];
}</code>

Good example: Delegate to the library method.

<code>int[] source = {1, 2, 3, 4, 5};
int[] target = Arrays.copyOf(source, source.length);</code>

4. Use isEmpty() to check emptiness

Bad example: Checking length() for strings or size() for collections.

<code>String text = "Pack";
if (text.length() == 0) { /* ... */ }
Set<String> datas = new HashSet<>();
if (datas.size() == 0) { /* ... */ }</code>

Good example: Use the constant‑time isEmpty() method.

<code>String text = "Pack";
if (text.isEmpty()) { /* ... */ }
Set<String> datas = new HashSet<>();
if (datas.isEmpty()) { /* ... */ }</code>

5. Avoid ConcurrentModificationException

Bad example: Removing elements from a list while iterating with a foreach loop.

<code>List<String> datas = new ArrayList<>();
// add elements
for (String s : datas) {
  if ("1".equals(s)) {
    datas.remove(s);
  }
}</code>

Good example: Use an iterator’s remove() method or removeIf() .

<code>List<String> datas = new ArrayList<>();
Iterator<String> it = datas.iterator();
while (it.hasNext()) {
  String value = it.next();
  if ("1".equals(value)) {
    it.remove();
  }
}
// or
datas.removeIf(item -> "1".equals(item));</code>

6. Pre‑compile regular expressions

Bad example: Compiling a pattern on each call with String.matches() .

<code>String str = "Hello, World";
if (str.matches("Hello.*")) {
  System.out.println(true);
}</code>

Good example: Compile once and reuse.

<code>private static final Pattern PATTERN1 = Pattern.compile("Hello.*");
public void validateString() {
  String str = "Hello, World";
  if (PATTERN1.matcher(str).matches()) {
    System.out.println(true);
  }
}</code>

7. Skip unnecessary existence checks before retrieval

Bad example: Checking containsKey before get on a map.

<code>if (params.containsKey("action")) {
  String value = params.get("action");
  // ...
}</code>

Good example: Retrieve directly and test for null .

<code>String action = params.get("action");
if (action != null) {
  // ...
}</code>

8. Efficiently convert collections to arrays

Bad example: Pre‑allocating an array with the collection size.

<code>String[] ret = datas.toArray(new String[datas.size()]);</code>

Good example: Pass an empty array; the method will allocate the correctly sized one.

<code>String[] ret = datas.toArray(new String[0]);</code>

9. Use default methods in interfaces

Bad example: Adding a new method to an interface forces all implementations to change.

<code>public interface Logger {
  void log(String message);
}
public class FileLogger implements Logger { /* ... */ }
public class ConsoleLogger implements Logger { /* ... */ }</code>

Good example: Provide a default implementation.

<code>public interface Logger {
  void log(String message);
  default void logError(String error) {
    // default handling
  }
}</code>

10. Adopt the modern Date/Time API

Bad example: Using the mutable java.util.Date class.

<code>Date birthday = new Date();</code>

Good example: Use the immutable classes from java.time (Java 8+).

<code>LocalDate date = LocalDate.now();
LocalDateTime dateTime = LocalDateTime.now();</code>

11. Use generics for type safety

Bad example: A raw List holding mixed types.

<code>List datas = new ArrayList();
datas.add(10);
datas.add("Hello");</code>

Good example: Declare the element type.

<code>List<Integer> datas = new ArrayList<>();
datas.add(10);
// datas.add("Hello"); // compile‑time error
</code>
JavaperformanceBest Practicescode qualityjava-17
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.