When using an anonymous innerclass inside a method, when we want to use a method parameter inside the anonymous innerclass, we must mark it as final.
Some details here:
Why do we use final keyword with anonymous inner classes?
But what happens when using a class attribute and not a method local attribute?
Simple usecase: a Spring service with a Guava function:
protected LovValueDAO lovValueDAO;
private final Function<String,LovValue> LOV_ID_TO_LOV = new Function<String,LovValue>() {
#Override
public LovValue apply(String input) {
return lovValueDAO.findById(input);
}
};
#Required
public void setLovValueDAO(LovValueDAO lovValueDAO) {
this.lovValueDAO = lovValueDAO;
}
Is it secure to declare such a Guava function?
According to my tests it works fine but what happens behind the hood?
The initialization order is:
Function is initialized
lovValueDAO is injected by spring through the
setter
Thus i guess, as the function is initialized first, that the lovValueDAO attribute used inside the function will not be a copy of the reference but the reference itself since once the DAO is really injected it works fine.
Am i correct?
And what happen if i use this code:
private final Function<String,LovValue> LOV_ID_TO_LOV = new Function<String,LovValue>() {
#Override
public LovValue apply(String input) {
return lovValueDAO = null;
}
};
Will my outside attribute protected LovValueDAO lovValueDAO; be set to null after i call the function?
Inner class holds an implicit reference to this of its enclosing instance (i.e. an instance of its declaring class in context of which it was created), so that access to fields of the declaring class is treated as a normal field access by that reference.
So, your inner class will see the current value of the field, and can change it as well.
Related
I implemented history by letting my forms to implement reconstructor, which is a lambda-returning method. It can be as simple as
#Override protected Supplier<MpxForm> reconstructor() {
return () -> new MyForm1();
}
or more complicated like e.g.,
#Override protected Supplier<MpxForm> reconstructor() {
State currentState = this.currentState;
Set<Item> selectedItems = this.selectedItems;
return () -> new MyForm2(currentState, selectedItems);
}
None of the lambdas needs access to the enclosing instance. That's important as it allows the form to be garbage collected.
However, with retrolambdas, they get converted to an inner class and as I was told, they use this as a reference to their surrounding class so they have a reference to their parent just like non-static inner classes.
This is unnecessary and IIUIC, retrolambda can do it right:
Lambda expressions are backported by converting them to anonymous inner classes. This includes the optimization of using a singleton instance for stateless lambda expressions to avoid repeated object allocation.
Obviously, the lambda in my first snippet is stateless, nonetheless, it was converted to a class having an instance variable of type MyForm1. The above optimization is missing.
The lambda in my second snippet has two instance variables and needs no reference to the enclosing class, so it could be converted to a nested class like
#RequiredArgsConstructor static class MyForm2$Lambda1 implements Runnable {
private final State currentState;
private final Set<Item> selectedItems;
#Override public void run() {
return new MyForm2(currentState, selectedItems);
}
}
Any chance to fix this?
With respect to the following class definition:
public final class ConfigComparer {
...some code ....
public ConfigComparer(String defaultFile, String siteFile)
throws NoSuchFieldException, IllegalAccessException {
this.defaultFile = defaultFile;
this.siteFile = siteFile;
defaultConfig = loadConfiguration(defaultFile);
siteConfig = loadConfiguration(siteFile);
load();
}
..... some code ....
}
Inside the constructor ConfigComparer, there are this.defaultFile = defaultFile; and this.siteFile = siteFile; what are these two this. used for or what are their design considerations?
this refers to the instance/object that your code is running inside.
this.defaultFile references the instance variable defaultFile of the class ConfigComparer.
defaultFile references the variable passed into the constructor.
When this is not specified, it always looks for local variables, before instance variables.
Within an instance method or a constructor, this is a reference to the current object — the object whose method or constructor is being called. You can refer to any member of the current object from within an instance method or a constructor by using this.
From within a constructor, this keyword to call another constructor in the same class. Doing so is called an explicit constructor invocation.
Source: http://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
As per the link, this refers to Within an instance method or a constructor, this is a reference to the current object
Your code constructor can be written without this keyword
like
public ConfigComparer(String defaultFile, String siteFile)
throws NoSuchFieldException, IllegalAccessException {
instance_defaultFile = defaultFile;
instance_siteFile = siteFile;
defaultConfig = loadConfiguration(defaultFile);
siteConfig = loadConfiguration(siteFile);
load();
}
In your constructor, the keyword this is necessary since both your instance variable and your method parameter are the same, the jvm needs to know what you are referring to and thats why you need to say
this.defaultFile = defaultFile
The class definition should be something like this:
public final class ConfigComparer {
private String defaultFile;
private String siteFile;
...some code ....
}
And, in the constructor, you are assigning the parameters (String defaultFile, String siteFile) to those attributes. Note that if the attributes would have a different name this is not required, but in this case it it, if not then you are assigning to the parameters their same value.
is it posible to read the "worldInfo" from another class ?
the following is part of the class that holds it:
public abstract class World implements IBlockAccess{
protected WorldInfo worldInfo;
//=====Stuff=====
public World(ISaveHandler par1ISaveHandler, String par2Str, WorldSettings par3WorldSettings, WorldProvider par4WorldProvider, Profiler par5Profiler, ILogAgent par6ILogAgent)
{
this.worldInfo.setWorldName(par2Str);
}
}
i want to use it in my class to get the name. "worldInfo.getWorldName"
EDIT 1:
Ok i created a class in the same package with the World.. "World_Spy.class"
public class World_Spy extends World{
public World_Spy(ISaveHandler par1iSaveHandler, String par2Str,
WorldProvider par3WorldProvider, WorldSettings par4WorldSettings,
Profiler par5Profiler, ILogAgent par6iLogAgent) {
super(par1iSaveHandler, par2Str, par3WorldProvider, par4WorldSettings,
par5Profiler, par6iLogAgent);
}
#Override
protected IChunkProvider createChunkProvider() {
return null;
}
#Override
public Entity getEntityByID(int i) {
return null;
}
String TheName = "";
public void gotIt(){
TheName = this.worldInfo.getWorldName();
System.out.println(TheName);
}
}
But when i call it from the main class it crashes the game..
World_Spy WName = new World_Spy(null, null, null, null, null, null);
Is it about the parameters?
In order to access worldInfo you'll have to extend World but as worldName is set to the second parameter of World constructor, it means you have to know it in your child class, so ..
For the functionality you want, either change the keyword protected to public, or create a public function in the class. It would look something like this:
public String getWorldName(){
this.worldInfo.getWorldName();
}
Actually, protected means it can be used by childclasses but also by any other class in the same package. So yes, you can use it by all classes in the same package even if they're not subclassing the abstract class
The class is abstract, so it cannot be initiated. You can read static variables from this class, but you cannot create object of this class. You can make this variabale as static and then you read it or inherit this class and make object of it or make it non-abstract and make object of it.
This variable holds constant? Make it static.
The field can be accessed directly if one of the following is true:
That another class extends World (inherited protected fields are
visible in derived classes, also World is not final and has non private constructor)
That another class belongs to the same package (protected fields are
visible in classes from the same package, same as package private).
The field can also be accessed through reflection from any other class after setting accessible property to true on that field (as long as security manager permits).
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.
Hey I'm trying to write a function that calls a static function based upon its generic arguments.
I'm having the following code:
public class Model<T extends Listable>
{
private Document doc;
/*
When the JavaBean is created, a Document object is made using
the Listable parameter. The request string for the specific
type is used to pull XML-data from the cloud.
*/
public Model()
{
try
{
doc = cloud.request(T.getRequestString());
}
catch(Exception e)
{
}
}
/*
getMatches (used in JSP as "foo.matches") generates a list
of objects implementing the Listable interface.
*/
public List<Listable> getMatches()
{
return T.generateMatches(doc);
}
}
How do I do this, I'm just getting something about static contexts.
'non-static method generateMatches(org.jdom.Document) cannot be referenced from a static context'
Turned comment into answer:
You can introduce an instance variable of type T and call generateMatches on that. You cannot call generateMatches on the type T itself.
You could e.g. inject this instance variable via the constructor and store it in a private variable:
private T instanceOfT;
public Model(T instanceOfT){
this.instanceOfT= instanceOfT;
}
In your getMatches method you can then do this:
return instanceOfT.generateMatches(doc);
Your problem is that you do not have handle to any object of class T. Just saying T.generateMatches(doc) means you are making a static call to static method in class T. You need to have a variable of type T to call instance methods.
What's the question ?
The reason is clear - the line "T.generateMatches(doc);" calls generateMatches through T, and T is type (class/interface), not instance.