Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [cdi-dev] It is not an inner class



On Sat, 10 Feb 2024 at 11:30, Philipp Kunz via cdi-dev <cdi-dev@xxxxxxxxxxx> wrote:
Just for curiosity, I'd like to understand in more detail the following statement [1] in the specs.

> * It is not an inner class.


I don't want to jump to conclusions but it seems to be easiest to express my question by just asking right away:

Would it be possible to just drop that statement "It is not an inner class."
and maybe replace the constructor requirement below with something like

* It has exactly one constructor or has exactly one constructor annotated @Inject

It would not be as easy as this. There are 3 kinds of inner classes: non-static member classes, local classes and anonymous classes. I assume you only had non-static member classes in mind (because static member classes already are beans, assuming all other conditions are satisfied).

Even with that in mind, your restriction on constructors is not enough. First off, there already is a similar restriction: there may only be one `@Inject` constructor. For normal scoped beans, the bean class also must have a zero-parameter constructor, so beans will usually have 2 constructors.

This immediately raises 2 problems:

1. Inner classes do not have a zero-parameter constructor. This constructor is used for creating a client proxy, so if we were to relax the rule on zero-parameter constructors, we would at least have to introduce an ordering requirement. Then, I'm not sure what should the CDI container pass as the enclosing instance in case of normal scoped beans: the contextual reference (= the client proxy), or the contextual instance? (I also feel like this is a bigger can of worms than I can imagine right now.)

2. Constructors of inner classes only implicitly declare the enclosing instance parameter if the inner class is not private. (If it is private, the enclosing instance parameter is synthetic. For all practical purposes, there's no difference, but from a specification perspective, a synthetic construct cannot be relied upon. The JLS does not guarantee it is there.) So we would have to add a restriction that disallows private inner classes.

Further, inner classes have visibility into the private state of their enclosing instances, which encourages using fields directly instead of calling methods. This is forbidden by CDI for normal scoped beans, except the prohibition cannot be enforced. Allowing inner classes to be beans makes this a bigger problem.

There might be more issues that I cannot think of at the moment, but the above looks like a convincing list of reasons for just not going there.

For integrating with existing code, it should be possible to declare a producer, but you'd need to think about lifecycle of the enclosing instance(s) and, if any of them are normal scoped, probably just bail out immediately (see the paragraph above about private state).

LT
 


Inner classes have constructors just like any other the first parameters of which
are the instance of the enclosing class and can be annotated just like any other constructor.
Furthermore, ProcessAnnotatedType could add an @Inject annotation to a constructor.

Particularly when dealing with existing or 3rd-party code, inner classes may be given.
Not being able to turn them into beans looks to me like a restriction
I don't at the moment see a conclusive reason for.
Is it really necessary?




_______________________________________________
cdi-dev mailing list
cdi-dev@xxxxxxxxxxx
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/cdi-dev

Back to the top