Running on Java 24-ea+25-3155 (Preview)
Home of The JavaSpecialists' Newsletter

318Getting Rid of Unused Warnings with _

Author: Dr Heinz M. KabutzDate: 2024-05-31Java Version: 22Category: Language
 

Abstract: We sometimes are forced by the Java language to declare variables that we never use, attracting the ire of the javac compiler. Since Java 22 we have a way to declare these as "unnamed" by using an underscore.

 

Welcome to the 318th edition of The Java(tm) Specialists' Newsletter. Time flies and I cannot believe that it is already one month since we had that delightful lunch at Thanasis Taverna, overlooking the little harbour of Tersanas. The word "Tersanas" means "shipyard" in Greek, and there are some ancient buildings where they repaired ships. The bay is sheltered from most wind except from the South-West. Fortunately that wind direction is not very common. It is a perfect place to chill, enjoy a cold beer and munch on some small fresh fish that Giannis brought in that morning.

javaspecialists.teachable.com: Please visit our new self-study course catalog to see how you can upskill your Java knowledge.

Getting Rid of Unused Warnings with _

Whenever a new subscriber joins The Java(tm) Specialists' Newsletter, they get a short welcome email that is written as if I wrote it to them personally. It isn't, and I state that in the email. However, the purpose is to start a short conversation, and over the years, thousands of Java programmers have written back. They always get a personal reply from me, and thus we get to know each other a bit better.

One of my recent subscribers is Larry Cable, and he sent me an interesting Java observation to share with you. Larry has been programming Java since 1.0.2, and you'll find his name in several places in the JDK codebase. Thanks Larry for joining my list and also for this fascinating tip.

A few years ago, I bought a used Mercedes Viano 3.5 liters. It's a luxury bus in which the previous owner carted princes and rock stars between Heraklion airport and Elounda. It's an old vehicle, but comfortable and large enough for our family of six to go somewhere together. Most of the time, I drive my tiny Suzuki Jimny, since it is so much easier to park in the cramped streets of Chania. However, the other day I drove the Mercedes, and, as unfortunately happens only too frequently with old skedonks, the orange engine light came on. My mechanics are great, but a bit far away, so I didn't look forward to the waste of time of taking it there. I turned the Merc off and on again and the light was still on (standard programmer fix-it-all).

Last Friday my son's band were playing on the other side of the Island, 4 hours drive away. He asked if they could take the Mercedes, and I was a bit concerned about the warning light. Who knows what the matter was now? It could be some irrelevant sensor like last time, or a more serious issue. This morning, I had to take our teenager to her final Greek language exam. Since we have more drivers than functioning cars (don't ask), I was asked to take the Mercedes. You know, the one with the orange warning light. When I started the engine, the warning light was off again. Phew. We got there in good time and she wrote an excellent exam. I don't like warning lights. They unnerve me. And I don't like warnings popping up when I code.

A few years ago there was a drive to get rid of warnings in the JDK code base. For example, we saw a concerted effort to add a serialVersionUID to classes implementing the java.io.Serializable interface, in order to quiet the warning of: [serial] serializable class XXX has no definition of serialVersionUID. That particular effort might have been a bit misguided, because it is useful to have the serializer pick up incompatibilities between object versions. For most other cases, I prefer to not see warning lights.

Larry Cable pointed out that within the try-with-resource context, if the variable is never used within the body, there was no way, prior to Java 22, to turn off the warning. For example, here is our first class:

import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;

public class IncorrectWarningDemo1 {
    public static void main(String... args) {
        try (var fc = FileChannel.open(Path.of("bla"));
             var flck = fc.lock()) { // or tryLock() ...
            // use try-with-resources to lock some file i/O ...
            // flck is not referenced in the try/catch/finally
            fc.write(ByteBuffer.allocate(10));
        } catch (IOException e) {
            // ...
        }
    }
}

When we compile this with -Xlint, we see

IncorrectWarningDemo1.java:9: warning: [try] auto-closeable
        resource flck is never referenced in body of
        corresponding try statement
    FileLock flck = fc.lock()) { // or tryLock() ...
             ^

This is incorrect. In the finally block, we automatically call flck.close() to unlock the FileLock. In Java 7 beta, we would have been able to skip the variable declaration and just do try (fc.lock()) {...}, but there were some strange compiler issues. Thus they forced us to have a declaration. But what if we don't actually explicitly use it? Here is an attempt to stop the warning light:

import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;

public class IncorrectWarningDemo2 {
    public static void main(String... args) {
        try (var fc = FileChannel.open(Path.of("bla"));
             @SuppressWarnings("unused") // shouldn't need this
             // SuppressWarnings does not turn of -Xlint warning
             var flck = fc.lock()) { // or tryLock() ...
            // use try-with-resources to lock some file i/O ...
            // flck is not referenced in the try/catch/finally
            fc.write(ByteBuffer.allocate(10));
        } catch (IOException e) {
            // ...
        }
    }
}

This quiets IntelliJ, but does not change the -Xlint warning:

IncorrectWarningDemo2.java:11: warning: [try] auto-closeable
        resource flck is never referenced in body of
        corresponding try statement
    FileLock flck = fc.lock()) { // or tryLock() ...
             ^

Fortunately, in Java 22 we now have JEP 456, which allow us to use underscores to mark unnamed variables. Thus we can do this:

import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;

public class IncorrectWarningDemo3 {
    public static void main(String... args) {
        try (var fc = FileChannel.open(Path.of("bla"));
             var _ = fc.lock()) { // or tryLock() ...
            // use try-with-resources to lock some file i/O ...
            // flck is not referenced in the try/catch/finally
            fc.write(ByteBuffer.allocate(10));
        } catch (IOException e) {
            // ...
        }
    }
}

No more compiler warnings! The engine light is off again. There are several places where this is useful in Java. For example, exceptions are often not used, and the convention is to call them "unused" or "ignored". We also often have lambda parameters that are not used. Underscores are also useful for working with pattern variables, but that will have to wait for another day.

Kind regards

Heinz

P.S. In the initial version of this newsletter, I used explicit variable declarations for flck and fc. Cay Horstmann and Jonathan Rosenne kindly pointed out that I could also have used var. Thank you, it didn't occur to me. I agree that var _ is even better. BTW, did you know that _ (underscore) has been a keyword since Java 9? Java keywords don't change often. In Java 1.2, they added strictfp, in Java 1.4, assert, in Java 5, enum, and that's it until Java 9. We have contextual keywords like module, sealed, etc. but we can use them in other context too.

 

Comments

We are always happy to receive comments from our readers. Feel free to send me a comment via email or discuss the newsletter in our JavaSpecialists Slack Channel (Get an invite here)

When you load these comments, you'll be connected to Disqus. Privacy Statement.

Related Articles

Browse the Newsletter Archive

About the Author

Heinz Kabutz Java Conference Speaker

Java Champion, author of the Javaspecialists Newsletter, conference speaking regular... About Heinz

Superpack '23

Superpack '24 Our entire Java Specialists Training in one huge bundle more...

Free Java Book

Dynamic Proxies in Java Book
Java Training

We deliver relevant courses, by top Java developers to produce more resourceful and efficient programmers within their organisations.

Java Consulting

We can help make your Java application run faster and trouble-shoot concurrency and performance bugs...