Search code examples
javamavenjava-22

Java _ keyword giving an error with Java 22


As i am aware, the _ for unnamed variables has been a preview feature [java:21] later released with JDK 22. This is the code in question

        char[] _ = { 'b', 'o', 'b' };

However i get this error

[ERROR]         '_' is a keyword from source level 9 onwards, cannot be used as identifier

Now i had assumed that its a issue with the JDK version Maven is set to build with so i changed pom.xml

    <properties>
        <maven.compiler.source>22</maven.compiler.source>
        <maven.compiler.target>22</maven.compiler.target>
    </properties>

And that hasn't resolved the issue - so i rather thought of checking it with mavens --show-version:

Maven home: [maven path]
Java version: 22.0.1, vendor: Amazon.com Inc., runtime: [my path]/java/22.0.1-amzn
Default locale: [locale]
OS name: [os info]

for the sake of simplicity i've removed some info

So how do i go about resolving this error?


Solution

  • You said:

    i included the line of code that produces the error. put it in your psvm or any other function and it will produce this same error.

    Nope, no such error. Works as documented.

    This compiles and runs:

    char[] _ = { 'b' , 'o' , 'b' };
    

    Full example:

    package work.basil.example.lang;
    
    import java.time.Instant;
    
    public class Underscore
    {
        public static void main ( String[] args )
        {
            System.out.println( Runtime.version( ) );
    
            int[] _ = { 1 , 2 , 3 };
    
            String _ = Underscore.getAlice( );
    
            char[] _ = { 'b' , 'o' , 'b' };
            char[] _ = Underscore.getChars( );
    
            System.out.println( "End of `main`. " + Instant.now( ) );
        }
    
        public static String getAlice ( )
        {
            System.out.println( "Getting Alice at " + Instant.now( ) );
            return "Alice";
        }
    
        public static char[] getChars ( )
        {
            System.out.println( "Getting chars at " + Instant.now( ) );
            return new char[] { 'b' , 'o' , 'b' };
        }
    }
    

    When run:

    22.0.1+10
    Getting Alice at 2024-07-09T19:31:16.269891Z
    Getting chars at 2024-07-09T19:31:16.272960Z
    End of `main`. 2024-07-09T19:31:16.273040Z
    

    By the way, with modern tooling you can collapse your source & target elements to one release element: <maven.compiler.release>22</maven.compiler.release>.

    Here is my complete POM.

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>work.basil.example</groupId>
        <artifactId>Ex</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <name>Ex</name>
        <!-- FIXME change it to the project's website -->
        <url>https://www.example.com</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.release>22</maven.compiler.release>
        </properties>
    
        <dependencies>
    
            <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter -->
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter</artifactId>
                <version>5.10.2</version>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
                <version>2.2.224</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j -->
            <dependency>
                <groupId>com.mysql</groupId>
                <artifactId>mysql-connector-j</artifactId>
                <version>8.4.0</version>
            </dependency>
    
            <dependency>
                <groupId>org.mongodb</groupId>
                <artifactId>mongodb-driver-sync</artifactId>
                <version>4.11.1</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.jetbrains/annotations -->
            <dependency>
                <groupId>org.jetbrains</groupId>
                <artifactId>annotations</artifactId>
                <version>24.1.0</version>
            </dependency>
    
    
        </dependencies>
    
        <build>
            <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (can be moved to parent pom) -->
                <plugins>
                    <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
                    <plugin>
                        <artifactId>maven-clean-plugin</artifactId>
                        <version>3.3.2</version>
                    </plugin>
                    <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
                    <plugin>
                        <artifactId>maven-resources-plugin</artifactId>
                        <version>3.3.1</version>
                    </plugin>
                    <plugin>
                        <artifactId>maven-compiler-plugin</artifactId>
                        <version>3.13.0</version>
                    </plugin>
                    <plugin>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <version>3.2.5</version>
                    </plugin>
                    <plugin>
                        <artifactId>maven-jar-plugin</artifactId>
                        <version>3.4.1</version>
                    </plugin>
                    <plugin>
                        <artifactId>maven-install-plugin</artifactId>
                        <version>3.1.2</version>
                    </plugin>
                    <plugin>
                        <artifactId>maven-deploy-plugin</artifactId>
                        <version>3.1.2</version>
                    </plugin>
                    <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
                    <plugin>
                        <artifactId>maven-site-plugin</artifactId>
                        <version>4.0.0-M13</version>
                    </plugin>
                    <plugin>
                        <artifactId>maven-project-info-reports-plugin</artifactId>
                        <version>3.5.0</version>
                    </plugin>
                </plugins>
            </pluginManagement>
        </build>
    </project>
    

    By the way, avoid char type. That type has been essentially broken since Java 2, and legacy since Java 5. As a 16-bit value, char is physically incapable of representing most characters. If using char, one emoji could ruin your whole day.