Import inner enum in Groovy script

2020-03-24 03:34发布

问题:

I have a Groovy class defined in Vehicles.groovy that contains some inner enums:

public class Vehicles {
  public enum Land {
    BICYCLE,
    CAR,
    TRAIN
  }

  public enum Water {
    SAILBOAT,
    MOTORBOAT
  }

  public enum Air {
    JET,
    HELICOPTER
  }
}

I'd like to reference these enums in a script run.groovy in the same directory as Vehicles.groovy.

Fully qualifying the enum instance works.

import Vehicles
println Vehicles.Land.BICYCLE

or

import static Vehicles.Land
println Vehicles.Land.BICYCLE

or

import Vehicles.Land.*
println Vehicles.Land.BICYCLE

correctly print BICYCLE.

However, I'd like to reference the Land enum without fully qualifying it.

I basically tried every combination of static/non-static, aliased/non-aliased, and star/non-star imports.

import Vehicles.Land or import static Vehicles.Land.* (or import Vehicles.Land as Land) give unable to resolve class errors. This seems weird because they're what one would do in Java (correct me if I'm wrong.)

If I try

import static Vehicles.Land
println Land.BICYCLE

or

import static Vehicles.Land as Land
println Land.BICYCLE

or

import Vehicles.Land.*
println Land.BICYCLE

, I get the error

Caught: groovy.lang.MissingPropertyException: No such property: Land for class: run
groovy.lang.MissingPropertyException: No such property: Land for class: run
        at run.run(run.groovy:2)

Similarly,

import Vehicles.Land.*
println BICYCLE

gives

Caught: groovy.lang.MissingPropertyException: No such property: BICYCLE for class: run
groovy.lang.MissingPropertyException: No such property: BICYCLE for class: run
    at run.run(run.groovy:2)

Adding package declarations to both Vehicles.groovy and run.groovy doesn't seem to help, either.

So...

  • What support does Groovy have for importing inner classes? Why is it it different from Java?
  • How can I get Groovy to allow me to reference non-fully-qualified inner enums?

Note: I'm using Groovy 1.8.6 and Oracle JDK 1.8.0_45.

回答1:

Groovy does support import nested classes, including enums. However to access them without full qualification, you'll need to import them in a non-static manner (unlike Java), or explicitly declare them static:

// Explicitly declare Water and Air as static to demonstrate
public class Vehicles {
  public enum Land { BICYCLE, CAR, TRAIN }
  public static enum Water { SAILBOAT, MOTORBOAT }
  public static enum Air { JET, HELICOPTER }
}

// Non-static nested enum needs non-static import (unlike Java)
import Vehicles.Land
println Land.BICYCLE

// Explicitly static nested enum can be static imported
import static Vehicles.Water
println Water.SAILBOAT

// Explicitly static nested enum can also be non-static imported as well!
import Vehicles.Air
println Air.JET

Working example: https://groovyconsole.appspot.com/script/5089946750681088

Unlike Java where enums are implicitly static, it appears that enums in Groovy are not implicitly static, hence why static imports don't work. This is because enums in Groovy aren't actually the same as the ones in Java, they made enhancements. Unfortunately it seems they have forgotten to tell the compiler to also make them implicitly static (at least as of 2.4.4).

My suggestion is to explicitly declare them static (if you can) as it would be keeping with the Groovy notion that valid Java is valid Groovy.



回答2:

Have you tried below?

import static Vehicles.Land.*

println BICYCLE

EDIT: is this what you are looking for?