Converting JS Functions to Java: 3 Patterns to Get Right
Converting JS Functions to Java: 3 Patterns to Get Right
Porting logic from JavaScript to Java happens more often than you'd expect — pulling frontend validation to the server, migrating a Node.js service to Spring, or translating a legacy script into a proper backend method. The control flow usually looks straightforward, but the type system differences between the two languages create a handful of spots where bugs hide quietly.
Here are the three patterns that trip people up most often, and how to handle each one.
Pattern 1: String Comparison — Replace == with .equals()
In JavaScript, comparing strings with == works as expected:
if (prodTpCd == '2011') { ... }
In Java, the same syntax compiles fine but compares references, not values. String literals often pass by accident due to the String Pool, but any string coming from a method return, API input, or object construction will be a different instance — and == will return false.
// Wrong — reference comparison
if (prodTpCd == "2011") { ... }
// Correct — value comparison
if ("2011".equals(prodTpCd)) { ... }
Why put the constant first? It's NPE protection. If prodTpCd is null, "2011".equals(null) safely returns false. Flip it, and prodTpCd.equals("2011") throws a NullPointerException immediately.
Pattern 2: Array Membership — Replace includes() with List.contains()
JavaScript's Array.prototype.includes() maps directly to Collection.contains() in Java.
You'll occasionally see this dual-check pattern in JS code:
cdList.includes(parseInt(prodTpCd)) || cdList.includes(prodTpCd)
This exists because JavaScript is loosely typed — prodTpCd might arrive as a string or a number depending on the source. The code hedges against both.
In Java, once you declare the parameter as String, the ambiguity disappears. One check is enough:
private static final List<String> CD_LIST = List.of("2006", "2007", "2019");
if (CD_LIST.contains(prodTpCd)) { ... }
Fixing the type at the method signature eliminates an entire class of defensive workarounds.
Pattern 3: Shared Lists — Replace Global Variables with static final
JavaScript typically manages shared lists as module-level or global variables:
const cdList = [2001, 2002, 2003]; // declared somewhere above
In Java, the idiomatic equivalent is a private static final constant on the class:
// Java 8
private static final List<String> CD_LIST = Arrays.asList("2001", "2002", "2003");
// Java 9+ — fully immutable
private static final List<String> CD_LIST = List.of("2001", "2002", "2003");
Prefer List.of() over Arrays.asList(). Both are fixed-size, but List.of() is truly immutable — calling add() or set() throws UnsupportedOperationException. It makes your intent explicit: this list is a constant, not a mutable collection.
Before and After
Before (JavaScript)
function getAuthMid(prodTpCd, taxtTpCd) {
let mid = '';
if (prodTpCd == '2011') {
mid = 'MID_A';
} else if (cdList.includes(parseInt(prodTpCd)) || cdList.includes(prodTpCd)) {
if (taxtTpCd == '1002' && (prodTpCd == "2006" || prodTpCd == "2007")) {
mid = 'MID_B';
} else {
mid = 'MID_C';
}
} else if (taxtTpCd == '1002') {
mid = 'MID_D';
} else {
mid = 'MID_E';
}
return mid;
}
After (Java)
private static final List<String> CD_LIST = List.of("2006", "2007", "2019");
public String getAuthMid(String prodTpCd, String taxtTpCd) {
String mid;
if ("2011".equals(prodTpCd)) {
mid = "MID_A";
} else if (CD_LIST.contains(prodTpCd)) {
if ("1002".equals(taxtTpCd)
&& ("2006".equals(prodTpCd) || "2007".equals(prodTpCd))) {
mid = "MID_B";
} else {
mid = "MID_C";
}
} else if ("1002".equals(taxtTpCd)) {
mid = "MID_D";
} else {
mid = "MID_E";
}
return mid;
}
The logic is identical. The difference is that the Java version won't silently misbehave at runtime.
Summary
| What to change | JavaScript | Java |
|---|---|---|
| String comparison | a == 'value' | "value".equals(a) |
| List membership | arr.includes(x) | list.contains(x) |
| Type hedging | includes(parseInt(x)) \|\| includes(x) | Fix parameter to String, use contains(x) |
| Shared list | Module/global variable | private static final List<String> |
Most JS-to-Java conversion bugs come from the type system difference, not the logic. Get string comparison and collection APIs right, and the rest of the conversion is mechanical.