Setting a final class attribute - java

Is it possible to set a value for a final attribute from a Private method called from the Constructor of that Object?
public class FinalTest {
private final Object a;
//Constructor
public FinalTest() {
setA();
}
private void setA() {
a = new Object;
}
}
For the above class, compiler gives me an error saying I can't set the value for 'a' from the method.
I understand that its not possible to set value for a final variable from outside a constructor, but in the above case, I am actually doing it in a way within the constructor. So why isn't this allowed?

It's not allowed because you could call setA() via some other non-constructor method later on which would violate the final protection. Since final is a compile time enforced operation, the compiler enforces final by forcing initialization to occur in constructors or in-line.
In your simple example, all looks good but if you later updated your class to something like the following, the problem become more obvious...
public class FinalTest {
private final Object a;
//Constructor
public FinalTest() {
setA();
}
private void setA() {
a = new Object;
}
public void doSomething() {
this.setA(); // not good because a is final
}
}

Just a note: The compiler has to assume the worst case scenario. By declaring an attribute "final", the compiler has to ensure that the attribute cannot be modified outside of the constructor.
In a case where the method is called using reflection (for example), the compiler would never see it, ever. It's a lot easier to prove something is possible than impossible, that is why the compiler works the way it does.

Final checking is done at compile time not at runtime time. In your case compiler can't be sure that setA would not be called from some other method.

Why do you need to set the value of final variable from a private method ?
You may do it in this way :
public class FinalTest {
private final Object a;
{
a=new Object();
}
//Constructor
public FinalTest() {
}
}
In this case the object will be initialized on every FinalTest initialization.

Related

Initializing "Default" final attributes in Java abstract class

I have an abstract class which is supposed to have an (int) attribute that can't be modified after initialization and is pre-set to 1; what is the best way to do it?
Should I make it final?
The requirement is that inside the class I will have one and only one constructor(with parameters), and no setters.
If so, how do I make it 1 by default if it's final and (I suppose) I'm going to initialize it in the constructor?
Thanks!
As a matter of fact your can even hard code it, if it will always be a constant value.
For example if your variable should always be 25 you can do something like this:
public abstract class Test
{
protected final int pressure = 25;
//Constructor
public Test()
{
// TODO Auto-generated constructor stub
}
}
But if you evaluate the value on runtime you need to set it with in the constructor of the Object:
public abstract class Test
{
protected final int pressure;
//Constructor
public Test(int pressure)
{
this.pressure = pressure;
}
}
Note that in this case the variable must not be assigned earlier!
The question, if a final variable should be used depends on it's purpose. A final variable can only be assigned once over it's entire lifetime. If you have to modify it in any kind you should not use it.
You could use constructor overloading to achive this. See the example:
public abstract class TestClass{
private final int otherParam;
private final int fixedParam;
public TestClass(final int otherParam){
this.otherParam = otherParam;
this.fixedParam = 1;
}
public TestClass(final int otherParam, final int fixedParam){
this.otherParam = otherParam;
this.fixedParam = fixedParam;
}
}
You should use a constructor with parameters to set your initial values. Then, as you say, don't create any setter, and be sure your fields are private, so that no one can access it.
This way, you will do what you want, having fields initialized but never change after that.

Call method once after any one of a few overloaded methods are called

In an abstract class I have a Predicate field, that is meant to be a combination of an unknown number of other Predicates. Joining the predicates works just fine but I am trying to have some way to know when the predicate has been initialized (or rather, just a way to know if it has or hasn't been initted).
Here is a short example of what I'm talking about:
public abstract class LimitedSystem implements Moveable {
private Predicate<Double> limits;
private final boolean initialized;
public void setLimits(SingleLimit... limits) {
List<Predicate<Double>> limitsList = Arrays.asList(limits);
this.limits = limitsList.stream().reduce(Predicate::and).orElse(x -> true);
}
public void setLimits(TwoLimits limits) {
this.limits = limits;
}
...
I am looking for ways to set initialized to true once (and once only, hence the final. I think I used it right) any of the setLimits have been called (they're overloaded).
I have other setLimits methods, but for the sake of generic code, I don't want to put a initialized at the end of each of the overloaded methods.
So my question is how can I, in a generic way, set the value of initialized after any of the setLimits methods has been called.
My first idea was to try to wrap the setLimits in some generic method which would call the correct overload by the parameter it gets, and then change initialized in that method. But I am not sure if that's a good idea.
Some other idea I got from another question1 was to put the setLimits in some interface or something similar. But I'm not sure how useful that might prove.
So how might this be accomplished?
(Also, if you happen to notice any design problems in this, please tell me because I'm trying to improve in that matter)
There's no need for separate fields:
private Predicate<Double> limits;
private final boolean initialized;
is basically
private Optional<Predicate<Double>> limits = Optional.empty();
if you want initialized to be set to true once limits is set,
provided you can guarantee that none of the setLimits methods can set it to Optional.empty() again. initialized == limits.isPresent().
You can't guarantee that a method is called in the body of an overridden method; in any case, this is a variant of the Call super antipattern.
You can do it like this:
abstract class Base {
final void setFoo(Object param) { // final, so can't be overridden.
setFooImpl(param);
thingThatMustBeCalled();
}
protected abstract void setFooImpl(Object param);
final void thingThatMustBeCalled() { ... }
}
class Derived extends Base {
#Override protected void setFooImpl(Object param) { ... }
}
But it's pretty ugly.

Refering "this" in a lazy initialization supplier?

For business decision applications, I run into a lot of cases where I must cache an expensive value with lazy initialization. So I leveraged generics and a Supplier lambda to encapsulate a lazy initialization.
import java.util.function.Supplier;
public final class LazyProperty<T> {
private final Supplier<T> supplier;
private volatile T value;
private LazyProperty(Supplier<T> supplier) {
this.supplier = supplier;
}
public T get() {
if (value == null) {
synchronized(this) {
if (value == null) {
value = supplier.get();
}
}
}
return value;
}
public static <T> LazyProperty<T> forSupplier(Supplier<T> supplier) {
return new LazyProperty<T>(supplier);
}
}
But I'd like to be able to use this also in cases where I can't initialize a property until after the object is created, because the object can only calculate this property after it is created (usually needing context of itself or other objects). However, this often requires a reference to this in the supplier function.
public class MyClass {
private final LazyProperty<BigDecimal> expensiveVal =
LazyProperty.forSupplier(() -> calculateExpensiveVal(this));
public BigDecimal getExpensiveVal() {
return expensiveVal.get();
}
}
As long as I can guarantee the LazyProperty's get() function is only called after MyClass is constructed (via the getExpensiveVal() method), there shouldn't be any partial construction issues due to the this reference in the supplier, correct?
Based on the little code you showed you should not have any problems but I would probably write your class like this to be more explicit:
public class MyClass {
private final LazyProperty<BigDecimal> expensiveVal;
public MyClass() {
this.expensiveVal = LazyProperty.forSupplier(() -> calculateExpensiveVal(MyClass.this));
}
public BigDecimal getExpensiveVal() {
return expensiveVal.get();
}
}
Your code will have one Problem which depends on the implementation of method calculateExpensiveVal.
if calculateExpensiveVal calls getExpensiveVal on the passed reference of MyClass you will get NullPointerException.
if calculateExpensiveVal creates a thread and pass the reference of MyClass, again you may run into the same problem as point 1.
But if you guarantee calculateExpensiveVal is not doing any of the things, then your code stand correct from Thread safety Perspective. MyClass will never be seen partially constructed
because of the final gaurantees provided by the JMM
After saying that even though your *calculateExpensiveVal may employ any one or both those points you are only going to have problem in getExpensiveVal method with NullPointerException.
your lazyProperty.get method is already thread safe so there woun'd be any problem.
Because you will always see fully constructed Supplier object because of final keyword (only if you didn't escaped 'this' reference to another thread) and you already have used volatile for value field which takes care of seeing fully constructed value object.

Exposing instance constants with non-static public final variables

I never see this kind of constants declaration in any Java code around me...
So i'd like to know if you see any drawback of using non-static final constants.
For exemple, i've declared a Guava function as a public constant of a given MaintenanceMode instance. I think it's better because if i created a getDecoratorFunction() it would create a new function instance each time...
Or the get function could return the single instance function that is kept private in the class, but it hads useless code... When we declare constants at class level, we declare directly the constants being public, we do not put them private and provide a public getter to access them...
public class MaintenanceMode {
/**
* Provides a function to decorate a push service with the appropriate decorator
*/
public final Function<PushService,PushService> MAINTENANCE_DECORATION_FUNCTION = new Function<PushService,PushService>() {
#Override
public PushService apply(PushService serviceToDecorate) {
return new PushServiceMaintenanceDecorator(serviceToDecorate,MaintenanceMode.this);
}
};
private final EnumMaintenanceMode maintenanceMode;
private final long milliesBetweenMaintenances;
private final Optional<ExecutorService> executorService;
public EnumMaintenanceMode getMaintenanceMode() {
return maintenanceMode;
}
public long getMilliesBetweenMaintenances() {
return milliesBetweenMaintenances;
}
public Optional<ExecutorService> getExecutorService() {
return executorService;
}
private MaintenanceMode(EnumMaintenanceMode maintenanceMode, long milliesBetweenMaintenances, ExecutorService executorService) {
Preconditions.checkArgument(maintenanceMode != null);
Preconditions.checkArgument(milliesBetweenMaintenances >= 0);
this.maintenanceMode = maintenanceMode;
this.milliesBetweenMaintenances = milliesBetweenMaintenances;
this.executorService = Optional.fromNullable(executorService);
}
}
And i can access this variable with:
pushServiceRegistry.decoratePushServices(maintenanceMode.MAINTENANCE_DECORATION_FUNCTION);
I guess it could lead to strange behaviours if my maintenanceMode was mutable and accessed by multiple threads, but here it's not.
Do you see any drawback of using this kind of code?
Edit: I can have multiple instances of MaintenanceMode, and all instances should be able to provide a different constant function according to the MaintenanceMode state. So i can't use a static variable that would not access the MaintenanceMode state.
The point of a getter would be dynamic dispatch. If you have no need for it, using a public final field is perfectly fine. I even routinely write bean-like objects that have no getters, just public final fields.
By making a constant non-static, you are basically saying that the constant can only be accessed when you have an instance of that class. But it is public (in the case of MAINTENANCE_DECORATION_FUNCTION) and it is part of that class so why not make it static? The constant is, after all, a constant and it does not require an instance of that class to be used elsewhere. The variable maintenanceMode is fine as it is a private constant.

Java - Class type from inside static initialization block

Is it possible to get the class type from inside the static initialization block?
This is a simplified version of what I currently have::
class Person extends SuperClass {
String firstName;
static{
// This function is on the "SuperClass":
// I'd for this function to be able to get "Person.class" without me
// having to explicitly type it in but "this.class" does not work in
// a static context.
doSomeReflectionStuff(Person.class); // IN "SuperClass"
}
}
This is closer to what I am doing, which is to initialize a data structure that holds information about the object and its annotations, etc... Perhaps I am using the wrong pattern?
public abstract SuperClass{
static void doSomeReflectionStuff( Class<?> classType, List<FieldData> fieldDataList ){
Field[] fields = classType.getDeclaredFields();
for( Field field : fields ){
// Initialize fieldDataList
}
}
}
public abstract class Person {
#SomeAnnotation
String firstName;
// Holds information on each of the fields, I used a Map<String, FieldData>
// in my actual implementation to map strings to the field information, but that
// seemed a little wordy for this example
static List<FieldData> fieldDataList = new List<FieldData>();
static{
// Again, it seems dangerous to have to type in the "Person.class"
// (or Address.class, PhoneNumber.class, etc...) every time.
// Ideally, I'd liken to eliminate all this code from the Sub class
// since now I have to copy and paste it into each Sub class.
doSomeReflectionStuff(Person.class, fieldDataList);
}
}
Edit
I picked the accepted answer based on what applied best to my problem, however it seems to me that all three of the current answers have their merits.
No, it's not possible without grabbing the stacktrace (which is imo nastier than your initial approach and for which I would in any way prefer Thread#getStackTrace() above new Exception()).
Rather do that job in a non-static initializer (or the default constructor) of the abstract class where you check the initialized status.
public abstract class SuperClass {
{
if (!isInitialized(getClass())) {
initialize(getClass());
}
}
}
The called methods in turn can be safely static.
yes, I use this often to initialize a static Log variable :
e.g. :
public class Project implements Serializable, Cloneable, Comparable<Project> {
private static final Logger LOG = LoggerFactory.getLogger(Project.class);
...
To get a class at runtime, you could do something along the lines of
public class Test {
public static void main(String[] args) {
try{
throw new Exception();
}
catch(Exception e){
StackTraceElement[] sTrace = e.getStackTrace();
// sTrace[0] will be always there
String className = sTrace[0].getClassName();
System.out.println(className);
}
}
}
Not pretty but will do the job (ripped from http://www.artima.com/forums/flat.jsp?forum=1&thread=155230).
This means you still make a call from the subclass (so is in the stack trace), but you don't need to include the XXX.class as an argument.

Categories

Resources