the usage of this in the class definition - java

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.

Related

Automatically add private qualifier to fields in eclipse

Is there a way to automatically add the private qualifier while new variables are declared in Eclipse?
In a way I would like to override the default access to private
I don't know of a way to do this.
However, the way i write code, it would rarely be necessary. That's because i rarely define fields by hand; instead, i let Eclipse create them, and when it does that, it makes them private.
Say i want to create a class Foo with a single field bar of type int. Start with:
public class Foo {
}
Put the cursor in the class body, hit control-space, and choose 'default constructor' from the proposals menu. You now have:
public class Foo {
public Foo() {
// TODO Auto-generated constructor stub
}
}
Delete the helpful comment. Now manually add a constructor parameter for bar:
public class Foo {
public Foo(int bar) {
}
}
Now put the cursor on the declaration of bar and hit control-1. From the proposals menu, choose 'assign parameter to new field':
public class Foo {
private final int bar;
public Foo(int bar) {
this.bar = bar;
}
}
Bingo. You now have a private field.
There is a similar sequence of automatic operations which can create a field from an existing expression in a method (first creating a local variable, then promoting it to a field).
If you consider it more important to you than performance and readability, I suppose you could configure a relatively convenient solution as follows. I wouldn't do this myself.
For class and instance variables, modify the class template in preferences to incorporate this:
private static Object fields = new Object () {
// declare all class variables here
};
private Object vars = new Object () {
// declare all instance variables here
};
For local variables, modify the method template in preferences to incorporate this:
private Object locals = new Object () {
// declare all local variables here
};
Class variable x will be declared in fields. It will be private at this.class.fields.x.
Instance variable y will be declared in vars. It will be private at this.vars.y.
Local variable z will be declared in locals. It will be private at locals.z.
If you do this, you can expect your entire program to be slower and use more memory that it would otherwise.

Get name of class during static construction

In C# I can assign the name of a class to a local static variable like this.
public class MyClass
{
private static string TAG = typeof(MyClass).Name;
}
I've found this very useful, because the value of the string automatically updated if the class is refactored to another name. Handy for tagging debug messages and such.
Is something like this possible in Java?
public class MyClass
{
private static String TAG = ????;
}
I know I could use getClass().getName() but that requires a reference to an object. Is there a way to do this on a static variable?
You don't need to assign the name of a class to field instead of writing.
MyClass.TAG
you can write
MyClass.class.getName();
If you really need to you can assign this to TAG but I don't see the point.
A trick is also available that does not require programmer's knowledge of the class name beforehand:
public class MyClass
{
private static String TAG =
new Object() { }.getClass().getEnclosingClass().getName();
}
This trick uses a nested anonymous Object subclass to get hold of the execution context. It has a benefit of being copy/paste safe in case of cloning your code across different classes...

Anonymous innerclass declaration for an instance attribute, using another instance attribute

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.

Regarding an example illustrating the usage of generic class syntax

In thinking in Java, page 566 gives the following example.
class CountedInteger {
private static long counter;
private final long id = counter++;
public String toString() { return Long.toString(id); }
}
public class FilledList<T> {
private Class<T> type;
public FilledList(Class<T> type) { this.type = type; }
public List<T> create(int nElements) {
List<T> result = new ArrayList<T>();
try {
for(int i = 0; i < nElements; i++)
result.add(type.newInstance());
} catch(Exception e) {
throw new RuntimeException(e);
}
return result;
}
public static void main(String[] args) {
FilledList<CountedInteger> fl = new FilledList<CountedInteger>(CountedInteger.class);
System.out.println(fl.create(15));
}
}
I have three questions with respect to this example.
1) What is the usage of private Class type? Why is it private?
2) Why do the following, in particular " this.type = type;"
public FilledList(Class<T> type) { this.type = type; }
3) The author claims:
Notice that this class must assume that any type that it works with
has a default constructor (one without arguments), and you’ll get an
exception if that isn’t the case.
I can not figure out how this statement was reflected in the above example. Thanks.
1) It doesn't have to be, but that's one of the things you do in Java--don't expose things that don't need to be exposed.
2) That sets the property to the parameter of the constructor--that's elemental Java.
3) Because of the type.newInstance() call; without a default (no-arg) constructor it will fail.
It doesn't have to be private, but generally it is good to hide internal fields in your classes, unless you want them to be accessible from the outside. I would also put final modifier on type filed to prevent modification.
This line assigns value passed in the class constructor to the instance field named type. Keyword this indicates that it is a this instance field.
The type.newInstance() code will fail if corresponding type doesn't have a default constructor.
BTW, the whole thing can be replaced with java.util.Collections.fill(list, value) call.
The type is just another instance variable. It is declared private
as to prevent access to it from outside of this class.
When an instance of this class FilledList is created, ie, when the
constructor which takes 1 arg is called, the instance variable type is
initilized with this arg value passed in the constuctor.
What type.newInstance() does is call the default no args constructor
of this type, this would throw an exception if the default
constructor is private.
1: all members of a class should be private or protected with respect to information hiding. But you dont have to do that
2: Inside any method ou have access to all parameters and all members-variables in that class. In this case the parameter-name is exactly the same as a member-variable. So in this case the parameter-name will win if you write type. this is pointing to the current instance and with this.type you indicate that you mean the member-variable and not the parameter. So this.type = type is in this case member = parameter.
3: newInstance with no parameters will call a default-constructor on T and if it doesn't exist an exception will be thrown. take a look at the link

Java static function on generics

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.

Categories

Resources