long
In short: A primitive integer type with 64 bits — for values that exceed the range of int (about ±2.1 billion).
In more detail: Long literals need an L suffix, otherwise Java first interprets the number as int and the compiler reports an error if it’s too large: long bigNumber = 10000000000L;. Often used for timestamps (milliseconds since 1970) or IDs in databases with very many entries.
In Depth
long bigNumber = 10000000000L; // without the L suffix: compiler error "integer number too large"
// Classic mistake: multiplying two ints overflows BEFORE assignment to long
int a = 100000, b = 100000;
long resultWrong = a * b; // int * int = int -> already overflows! Wrong result
long resultCorrect = (long) a * b; // cast BEFORE the multiplication forces long arithmetic
long timestamp = System.currentTimeMillis(); // milliseconds since 1/1/1970 (Unix epoch)The multiplication overflow bug is especially tricky, because it can’t be prevented by the target type declaration (long resultWrong): Java first computes a * b entirely as an int expression (since both operands are int), and ONLY the finished — already overflowed — result is subsequently “cast up” into a long variable. The cast therefore has to be BEFORE or ON one of the operands, not only at the assignment. System.currentTimeMillis() always returns a long value, because the number of milliseconds since 1970 has long since exceeded the range of int (this was historically one of the triggers for the “Year 2038 problem” in systems that instead store seconds as a 32-bit int).
long vs. Long (wrapper class)
Besides the primitive long (lowercase), there’s the wrapper class Long (capitalised, a genuine object) — needed anywhere generic collections like List<Long> are used, since generics can only work with object types, not primitive types directly. Java usually converts automatically between both forms (auto(un)boxing), which occasionally leads to subtle performance traps when many such automatic conversions occur within a loop.
long in practice: IDs and timestamps
Besides timestamps, long is also the default type for database primary keys (IDs) in systems with potentially very many records — an int primary key would be exhausted after over 2.1 billion entries, which can genuinely become an issue for long-lived, strongly growing systems. Many frameworks and database schemas therefore preemptively use long/BIGINT for primary keys, even when the current amount of data doesn’t push that limit yet.
See also: byte, short, double, Wrapper Classes