Community
Participate
Working Groups
Coming off bug 52105, these are some proposals for doc clarification and possible enhancements wrt static initialization involving fields declared in an aspect. (1) During static initialization, expressions can only use static fields that have been defined, which means order should be defined, but AFAIK, we have not defined an order in the semantics. It seems possible for an implementation to order field initialization so it works (and warn on cycles), but the order should probably be defined as the order in which they appear in the types declaring them. The order between types probably should be undefined, but could be defined by precedence (which suggests that classes should be permitted in declare precedence statements). (2) Currently, static ITD fields can be defined in their declaration or in advice on static initialization, which limits the expressions available for final fields and makes initialization of such fields awkward. So perhaps an aspect should be able to declare a static initialization block on another type, something like: TargetType.<clinit>{ ... init code } ? init code" might have to be restricted in some way? ? "TargetType.new {}" -- distinct from instance in having no ()? This makes possible complex mutual definitions, e.g., public static final Target.List ALL; public static final Target.List ONE; public static final Target.List TWO; Target.<clinit> { ArrayList list = new ArrayList(); ONE = new Something("one"); TWO = new Something("two"); list.add(ONE); list.add(TWO); ALL = Collections.unmodifiableList(list); }
I'm very reluctant to add this feature as I personally believe that static intertype field declarations are almost always a bad design style and don't see any good reasons to make them easier to use. Why would you want to use a static final ITD instead of just putting the static final field on the aspect?
Static fields (final or not) declared in aspects are a feature of the language that programmers might like to use for whatever reasons they have. They might want to publish a public logger on each class; while the build depends on the aspect, the client classes do not do so directly. They may be under a requirement to make any static fields final (see, e.g., the EJB spec). It's also more convenient to have a block for initialization to be able to handle exceptions. The workaround for non-final fields and fields defined after other fields is after () returning : staticinitialization(Foo) { ... Foo.LOGGER = ...; } which of course gives you the block but not the finality. One hack for finality could be to define the static final in terms of another nonfinal static and hope that Java does the right thing. (Now there's bad style...) Let's see if any users actually want this. (If you are a user and need this, please explain why in the bug.)
Re. the last comment on this enhancement request "Let's see if any users actually want this. (If you are a user and need this, please explain why in the bug.)" we've had no user votes for the feature, and Jim's vote against, so I'm proposing we close this off.