What 'final' keyword next to the field stands for? - spring

In a legacy code, I'm working with, I found the following thing:
#Autowired
final lateinit var controller: CustomController
what does this final keyword mean here?
In a Kotlin documentation I found a short description about final keyword that is blocking overriding of the methods in open classes but no information about fields. Also - the class within which I found the line is not open

A final property or a method in Kotlin prevents overriding of the field / method. That being said, Kotlin by default considers a property or a method/function to be final unless specified by the keyword open. In your case, the final keyword is redundant.
Here's a small demo test case to illustrate the same.
open class Parent {
open val someValue = 0
final val otherValue = 13 // redundant modifier 'final' warning in Android Studio
}
class Child : Parent() {
override val someValue = 5
// override val otherValue = 19 // compile error
}
There is an interesting problem called Fragile Base Class in OOP and why some languages like Kotlin prefer final by default.

What you have there is a property, not a field.
It looks just like a field, as it would in Java; but in Kotlin, it actually defines a public getter method, a public setter method, and a private backing field*.
So the final modifier applies to the accessor methods, preventing those from being overridden in a subclass.  (As you say, the backing field itself can't be overridden anyway.)
As Siddharth says, final is the default in Kotlin, so you usually wouldn't need to specify it, though there are a few situations in which it would be needed — e.g. if it were already overriding something, or you were using the all-open or kotlin-spring compiler plug-ins.  (The use of #Autowired suggests that this is a Spring module, which probably explains why final is needed here.)  In any case, your IDE would probably indicate where it's not needed, e.g. by showing it greyed-out.
(* Only the getter is necessary; the setter isn't generated for a val, and the backing field isn't generated if you override the accessor(s) and they don't refer to it.)

Related

Spring boot `#Value` is always zero, despite default

I am using
#Service
public class Foo
{
#Value ("${this.does.not.exist: 10}")
private static int bar;
}
Because the value does not exist in the configuration, I was expecting bar to have value 10 but it is 0.
I also tried #Value ("${this.does.not.exist: #{10}}") as per this answer, it's still zero.
Why didn't this work?
I omitted the static keyword in the OP (now edited) and that was the fault.
The following code works for me:
#Service
public class MyService {
#Value("${this.does.not.exist: 10}")
private int val;
With the last version of spring-boot (and it should with any other version basically).
So the issue must be elsewhere.
Please check the following:
Make sure that Foo is indeed managed by spring (it finds it in the component scanning process). Otherwise no-one will inject the value.
Make sure that you're not trying to read the value from constructor or something:
In spring it first creates the object (and at that moment the value of the field is 0 indeed) and only then triggers a bean post processors for injecting values, autowiring, etc.

Kotlin init not picking up value from #Value

I want to initialise a member variable from a value I pick from ENV but it is not available in init block as it gets picked up after object initialisation
private lateinit var needValueHere: String
#Value("\${CLIENT_ID:NA}")
private val CLIENT_ID: String = ""
init {
this.needValueHere = this.CLIENT_ID
}
This is a simplified version of the actual problem.
I have verified the value is available in the member functions.
Your object is constructing by the following way:
Create object (e.g. call constructor)
Via reflection: put dependencies (e.g. fill values under #Autowired, #Value and other annotations).
Your init block is part of constructor, e.g. all Spring-related items aren't initialized here.
How you can fix this:
Extract properties to the type-safe configuration (please see official docs here)
Use notation of class like below.
Create private lateinit var field and don't call it until Spring initialization finishing (this is useful for integration tests, e.g. test methods start only after full warmup). Another option - use kotlin lazy notation. However whole this item couldn't be named as "good code".
class MyService(#Value("\${CLIENT_ID:NA}") private val needValueHere: String) {
/* */
}

Why is the Java 8 Optional class final? [duplicate]

I was playing with the following question: Using Java 8's Optional with Stream::flatMap and wanted to add a method to a custom Optional<T> and then check if it worked.
More precise, I wanted to add a stream() to my CustomOptional<T> that returns an empty stream if no value is present, or a stream with a single element if it is present.
However, I came to the conclusion that Optional<T> is declared as final.
Why is this so? There are loads of classes that are not declared as final, and I personally do not see a reason here to declare Optional<T> final.
As a second question, why can not all methods be final, if the worry is that they would be overridden, and leave the class non-final?
According to this page of the Java SE 8 API docs, Optional<T> is a value based class. According to this page of the API docs, value-based classes have to be immutable.
Declaring all the methods in Optional<T> as final will prevent the methods from being overridden, but that will not prevent an extending class from adding fields and methods. Extending the class and adding a field together with a method that changes the value of that field would make that subclass mutable and hence would allow the creation of a mutable Optional<T>. The following is an example of such a subclass that could be created if Optional<T> would not be declared final.
//Example created by #assylias
public class Sub<T> extends Optional<T> {
private T t;
public void set(T t) {
this.t = t;
}
}
Declaring Optional<T> final prevents the creation of subclasses like the one above and hence guarantees Optional<T> to be always immutable.
As others have stated Optional is a value based class and since it is a value based class it should be immutable which needs it to be final.
But we missed the point for this. One of the main reason why value based classes are immutable is to guarantee thread safety. Making it immutable makes it thread safe. Take for eg String or primitive wrappers like Integer or Float. They are declared final for similar reasons.
Probably, the reason is the same as why String is final; that is, so that all users of the Optional class can be assured that the methods on the instance they receive keep to their contract of always returning the same value.
Though we could not extend the Optional class, we could create our own wrapper class.
public final class Opt {
private Opt() {
}
public static final <T> Stream<T> filledOrEmpty(T t) {
return Optional.ofNullable(t).isPresent() ? Stream.of(t) : Stream.empty();
}
}
Hope it might helps you. Glad to see the reaction!

Annotations for Java enum singleton

As Bloch states in Item 3 ("Enforce the singleton property with a private constructor or an enum type") of Effective Java 2nd Edition, a single-element enum type is the best way to implement a singleton. Unfortunately the old private constructor pattern is still very widespread and entrenched, to the point that many developers don't understand what I'm doing when I create enum singletons.
A simple // Enum Singleton comment above the class declaration helps, but it still leaves open the possibility that another programmer could come along later and add a second constant to the enum, breaking the singleton property. For all the problems that the private constructor approach has, in my opinion it is somewhat more self-documenting than an enum singleton.
I think what I need is an annotation which both states that the enum type is a singleton and ensures at compile-time that only one constant is ever added to the enum. Something like this:
#EnumSingleton // Annotation complains if > 1 enum element on EnumSingleton
public enum EnumSingleton {
INSTANCE;
}
Has anyone run across such an annotation for standard Java in public libraries anywhere? Or is what I'm asking for impossible under Java's current annotation system?
UPDATE
One workaround I'm using, at least until I decide to actually bother with rolling my own annotations, is to put #SuppressWarnings("UnusedDeclaration") directly in front of the INSTANCE field. It does a decent job of making the code look distinct from a straightforward enum type.
You can use something like this -
public class SingletonClass {
private SingletonClass() {
// block external instantiation
}
public static enum SingletonFactory {
INSTANCE {
public SingletonClass getInstance() {
return instance;
}
};
private static SingletonClass instance = new SingletonClass();
private SingletonFactory() {
}
public abstract SingletonClass getInstance();
}
}
And you can access in some other class as -
SingletonClass.SingletonFactory.INSTANCE.getInstance();
I'm not aware of such an annotation in public java libraries, but you can define yourself such a compile time annotation to be used for your projects. Of course, you need to write an annotation processor for it and invoke somehow APT (with ant or maven) to check your #EnumSingleton annoted enums at compile time for the intended structure.
Here is a resource on how to write and use compile time annotations.

Spring-Wicket: optional but named bean still required

Consider following (wicket) code:
#SpringBean(required=false)
private StatusCheckService service;
In my use case there is no bean of type StatusCheckService in my context.
This is not a problem, it is marked as optional so the (wicket) page will initialize just fine.
However:
#SpringBean(name = "statusCheckService", required=false)
private StatusCheckService service;
This fails:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'statusCheckService' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1095)
at org.springframework.beans.factory.support.AbstractBeanFactory.isSingleton(AbstractBeanFactory.java:400)
at org.springframework.context.support.AbstractApplicationContext.isSingleton(AbstractApplicationContext.java:1113)
at org.apache.wicket.spring.SpringBeanLocator.isSingletonBean(SpringBeanLocator.java:100)
at org.apache.wicket.spring.injection.annot.AnnotProxyFieldValueFactory.getFieldValue(AnnotProxyFieldValueFactory.java:140)
I would expect it makes no difference. OK, there is no bean with such a name but I marked it as optional so why the exception? Is there any way around this?
By doing a usage search in eclipse, you can see that the only time the annotation is queried for its required value is on line 215 of AnnotProxyFieldValue:
if (names.isEmpty())
{
if (annot.required())
{
throw new IllegalStateException("bean of type [" + clazz.getName() + "] not found");
}
return null;
}
Here you can see that the 'required' field of the #SpringBean annotation is only used if the names list (set higher in the function) is empty...
This explains the behaviour you are experiencing, because when you don't specify a name, the names list is empty (because it could not find your class), and null is returned. However when you do specify a name it doesn't bother trying to see if the class exists, and so sends your supplied class-name for spring to look up which proceeds to complain when it cannot find the class.
This could be a bug depending on designers intentions, personally I think if you have specified that the field is not required then the function should return early... If you agree then maybe consider putting in a jira ticket with a quick start.
As for a solution, you haven't mentioned much about your use case, and why you need to set the name even though you do not require the bean to be injected. But assuming you are doing it to dynamically inject the bean based on certain criteria, you could do something like the following: (untested)
In your class where the SpringBean is injected, replace:
#SpringBean(name="statusCheckService", required=false)
private StatusCheckService service;
With:
MyCustomSpringBeanInjector injectedService;
And then MyCustomSpringBeanInjector class is something like:
import org.apache.wicket.injection.Injector;
import org.apache.wicket.spring.injection.annot.SpringBean;
public class MyCustomSpringBeanInjector
{
#SpringBean public StatusCheckService service;
public MyCustomSpringBeanInjector()
{
Injector.get().inject(this);
}
}
Then back in the class where the SpringBean was being injected, put something like:
if(statusCheckServiceRequired)
injectedService = new MyCustomSpringBeanInjector();
and replace "service." with "injectedService.service" where necessary.
Obviously this is a qwik-e fix off the top of my head, and I'm sure there's a better way of doing it, but you get the idea! :)
Best of luck!

Resources