If you use the LaTeX listings package to typeset Java, you’ve probably noticed that modern Java has moved faster than the package itself. Records, var, and text blocks may not highlight correctly out of the box. The good news: the listings package is extensible so that you can teach it “modern Java” with a tiny language definition.
The minimal language extension for Java 17
Here’s a drop‑in snippet that builds on the stock Java lexer to support key Java 17 features:
|
1 2 3 4 5 6 |
\lstdefinelanguage{Java17}{ language = Java, morekeywords = {var,record}, deletekeywords={label}, morestring=[b]""" } |
What each line does:
- language = Java: inherit all of the listings’ built‑in Java rules.
- morekeywords = {var,record}: colorize var and record as keywords (var is contextual, but highlighting it improves readability in code listings).
- deletekeywords = {label}: avoid mistakenly highlighting labeled statements like label: for (…) { … }. label is not a Java keyword; removing it prevents false positives.
- morestring=[b]”””: treat triple quotes as a balanced string delimiter so Java text blocks highlight as a single string.
Using it in your document
Activate the language globally:
|
1 |
\lstset{language=Java17} |
…or per listing:
|
1 2 3 |
\begin{lstlisting}[language=Java17] // code here \end{lstlisting} |
If you already have a custom style (e.g., mystyle) with colors and fonts, combine them:
|
1 |
\lstset{language=Java17, style=mystyle} |
Minimal working example
This is a compact MWE you can compile with pdflatex, xelatex, or lualatex. Adjust the style to your taste:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
\documentclass{article} \usepackage[T1]{fontenc} \usepackage[utf8]{inputenc} % not needed on XeLaTeX/LuaLaTeX \usepackage{xcolor} \usepackage{listings} % Simple, readable default style \lstdefinestyle{mystyle}{ flexiblecolumns=true, keepspaces=true, tabsize=4, showstringspaces=false, basewidth={0em,0em},, numbers=left, basicstyle=\scriptsize, commentstyle=\itshape, stringstyle=\ttfamily, } % Modern Java language extension \lstdefinelanguage{Java17}{ language=Java, morekeywords={var,record}, deletekeywords={label}, morestring=[b]""" } \begin{document} \section*{Demo} With the default \texttt{Java} language definition: \begin{lstlisting}[language=Java,style=mystyle] record Point(int x, int y) {} class Demo { public static void main(String[] args) { var msg = """ Hello, Java 17 "text blocks!" """; System.out.println(msg); label: for (int i = 0; i < 1; i++) { break label; // 'label' is not highlighted as a keyword } } } \end{lstlisting} \noindent With the \texttt{Java17} language definition: \begin{lstlisting}[language=Java17,style=mystyle] record Point(int x, int y) {} class Demo { public static void main(String[] args) { var msg = """ Hello, Java 17 "text blocks!" """; System.out.println(msg); label: for (int i = 0; i < 1; i++) { break label; // 'label' is not highlighted as a keyword } } } \end{lstlisting} \end{document} |
Here’s the result, where you can see the differences (note in the standard behavior the wrong highlighting of the double-quoted string in the text-block):
Happy highlighting! 🙂
