Spring is a comprehensive framework for building Java applications. Spring Boot is an extension of Spring that further automates configuration of Spring's features, simplifies dependency declarations in Maven or Gradle, and adds some metrics and information points.
Sharing an object between processes, or between invocations of a process, or storing an object in a file or database, requires saving enough information to reconstruct the object later. The process of saving the object by serializing it, writing each field (and each field of a member object) in such a form as to be savable. The reverse process is called deserialization.
Java has a "native" serialization scheme, using the marker interface Serializable. While still a valid choice for serialization, it has largely been replaced by JSON and XML for serialization, as those formats are widely used, both within and outside of the Java community.
The de facto standard for serialization is the Jackson library (com.fasterxml.jackson.*). Jackson can handle either JSON or XML; it does most of what you need without any customization; and any customizations you need are fairly easy to apply. Some of these are described below, in the Serialization and Deserialization sections.
Since Jackson (and other) deserializers use setters to deserialize, you can’t deserialize to an immutable object, right? Wrong. Use @JsonCreator.
public class Immutable {
private final String foo;
private final String bar;
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
public Immutable(@JsonProperty(“foo”) String foo,
@JsonProperty(“bar”) String bar) {
this.foo = foo; this.bar = bar;
}
}
There are other modes besides PROPERTIES; DEFAULT means use setters, and DELEGATING is useful for use with constructors that don’t specify all properties. There is also a paradigm for using builders. See here for some examples.
IntelliJ Idea and Eclipse both support remote debugging. In IntelliJ, create a “Remote” configuration: Best to use “Attach to remote JVM”. Just fill in “Host” and “Port” on the form. IntelliJ will create a command-line option to use when launching Java on the remote. Make sure you choose the correct JDK version on the popup menu. That will insure that you can actually debug remotely. (There was a change starting with Java 9; See this link for details: Java Application Remote Debugging | Baeldung )
You're doing test-driven development, right? (Right?)
public static void setSeed(long seed) {
RANDOM.setSeed(seed);
}
These are just a few things that might not be obvious, even to an experienced Java programmer, but that I have picked up over the years.
String foo = null;
System.out.println(foo instanceof String); // false
a >> 31 | -a >>> 31
Try it out, prove to yourself that this works.
This section may look like a “hall of shame,” but the intent is to provide examples of what not to do.
int popularity;
doc.addField("popularity", Math.min(Integer.MAX_VALUE, popularity));
For this discussion, it does not matter what happens in addField(). The call to Math.min() will always return an int/Integer; if popularity happens to be the same as Integer.MAX_VALUE, you will get Integer.MAX_VALUE. Otherwise, you will get whatever value popularity has. In either case, you get popularity’s value. Don’t make unnecessary method calls--they’re not free. (Rather, if your compiler is "smart enough," they’re free. What does "smart enough" mean? It means, "smart enough to fix or ignore a method call that doesn't make sense to a smart human who understands all the issues." Don't ever count on your compiler being "smart enough" for that.) On the other hand, if popularity is a long, then Math.min((long)Integer.MAX_VALUE, popularity) returns a long, and makes perfect sense.
if (condition) {
<statements>
} else {
<same statements as in the if block>
}