One of the legal modifiers you can use with method local inner classes is abstract.
For example:
public class Outer {
public void method(){
abstract class Inner{
}
}
}
Is there any situation where you would actually use this?
You have to know this for the SCJP exam.
The are some invalid assumptions in the original question. That something is legal/valid Java doesn't mean that it is something that you need to use, or need to know.
I can't recall that the SCJP contains odd corner case questions.
I tried to come up with a case where I would have used an abstract class declared in a method, but everything looks very odd, and reeks of bad design.
Here's however a code example that I came up with (still bad code design IMHO)
public class BatchExecutor {
public static enum ResultNotification {
JMS,
MAIL
};
public Runnable createRunnable(ResultNotification type) {
abstract class Prototype implements Runnable {
public void run() {
performBusinessLogic();
publishResult();
}
abstract void publishResult();
}
switch (type) {
case JMS: {
return new Prototype() {
void publishResult() {
//Post result to JMS
}
};
}
case MAIL: {
return new Prototype() {
void publishResult() {
//Post result to MAIL
}
};
}
}
return null;
}
private void performBusinessLogic() {
//Some business logic
}
}
I can think only in this case
class Outer {
public void method() {
abstract class A {
void bar(){}
abstract void foo();
}
class B extends A {
#Override
void foo() {
}
}
final class C extends A {
#Override
void foo() {
}
}
A a1 = new B();
A a2 = new C();
}
}
But I can't imagine real usage
IMHO, this feature has NO real use. There's a couple of possible abuses, but there are many other ways to write bad code, you needn't learn this one. :D
Whenever you try to make use of an abstract method-local class, you need to define at least two concrete method-inner classes. This means you end up with a method containing at least three classes, the method gets quite long and that's quite a bad style.
You have to know this for the SCJP exam.
I really hope not. Method-local inner classes are already useless enough to be considered a corner case (you should understand them but probably never use them).
IMHO, a person asking this in an exam misunderstood Java badly. There can't be accessibility modifiers on a local class since (lacking method literals) the class can't be accessed from the outside anyway. There can be abstract and final modifiers, since there's no reason to forbid them. There are good reasons to allow them: orthogonality and the Principle of least astonishment.
Is there any situation where you would actually use this?
Let S1 denote all situations in which you need an abstract class.
Let S2 denote all situations in which you need a local class.
The answer to your question can be found by examining S1 ∩ S2
Related questions:
What benefit do method-local inner classes provide in Java?
Use of Java [Interfaces / Abstract classes]
Clarification: My point is that the two features (abstract classes and local classes) are two completely orthogonal features of the language. Understanding when each feature is useful is the key to understanding when they are both useful at the same time.
You can get the use here http://java-questions.com/InnerClass_interview_questions.html
which says
The inner class declared inside the method is called method local inner class. Method local inner class can only be declared as final or abstract. Method local class can only access global variables or method local variables if declared as final
ie You can declare the static variables in the inner call and use them in the methods.
EDIT: Why abstract:
Because if you dont want to create the objects of the inner class. If you create the object in the method then it will be stored in the heap and it is not freed even if the method execution completes as there might be an external reference for this object when it is returned from the method.
So it depends on whether you want to create an instance or not. If you want to create then use final modifier.
the only real use I can imagine is for nodes in a data structure
that way you can differentiate methods from sentinel nodes and normal data nodes which can be really handy in recursive algorithms and you don't have to null check each time
No, there is no good use for abstract classes (or classes in general) inside methods.
It would only make sense if only that particular method would need that particular class and would also implement it. Actually having that situation maybe happens once in trillions of methods you write.
Check out the section titled "Hierarchies of Inner Classes" on this page.
The gist is that you can treat the inner class as just another abstract member that needs to be overridden/implemented. I don't necessarily agree with it (I would probably just define the inner class separately), but I've seen things like this in the wild.
Here's their example code:
public abstract class BasicMonitorScreen {
private Dimension resolution;
public BasicMonitorScreen(final Dimension resolution) {
this.resolution = resolution;
}
public Dimension getResolution( ) {
return this.resolution;
}
protected abstract class PixelPoint {
private int x;
private int y;
public PixelPoint(final int x, final int y) {
this.x = x;
this.y = y;
}
public int getX( ) {
return x;
}
public int getY( ) {
return y;
}
}
}
public class ColorMonitorScreen extends BasicMonitorScreen {
public ColorMonitorScreen(final Dimension resolution) {
super(resolution);
}
protected class ColorPixelPoint extends PixelPoint {
private Color color;
public ColorPixelPoint(final int x, final int y, final Color color) {
super(x, y);
this.color = color;
}
public Color getColor( ) {
return this.color;
}
}
}
I think it can be useful to reduce the scope of methods in certain conditions.
For exemple, I use it in unit tests. Sometimes you need an utility method to reduce the verbosity of a test. But this utility method may be related to the current test dataset, and can't be reused outside of this test.
#Test
public void facetting_is_impacted_by_filtering() {
// given
String userId = "cd01d6b08bc29b012789ff0d05f8e8f1";
DocumentSolrClient client = solrClientsHolder.getDocumentClient(userId);
//
final SolrDocument doc1 = createDocument(userId);
doc1.setAuthorName("AuthorName1");
doc1.setType("Type1");
doc1.setUserTags(Arrays.asList("UserTag1", "UserTag1bis","UserTag1bisbis"));
doc1.setSenderTags(Arrays.asList("SenderTag1", "SenderTag1bis"));
doc1.setCreationDate( new Date(EnumDateRange.CURRENT_DAY.getBegin().getTime()+1000) );
doc1.setLocation(DocumentLocation.INBOX);
client.index(doc1);
//
final SolrDocument doc2 = createDocument(userId);
doc2.setAuthorName("AuthorName2");
doc2.setType("Type2");
doc2.setUserTags(Arrays.asList("UserTag2"));
doc2.setSenderTags(Arrays.asList("SenderTag2"));
doc2.setCreationDate( new Date(1000) ); // cree il y a tres longtemps
doc2.setLocation(DocumentLocation.SAFE);
client.index(doc2);
//
final List<DateRange> facettedRanges = Arrays.<DateRange>asList(
EnumDateRange.CURRENT_DAY,
EnumDateRange.CURRENT_YEAR,
EnumDateRange.BEFORE_CURRENT_YEAR
);
class TestUtils {
ApiSearchRequest baseFacettingRequest(String userId) {
ApiSearchRequest req = new ApiSearchRequest(userId);
req.setDocumentTypeFacets(true);
req.setSenderNameFacets(true);
req.setSenderTagsFacets(true);
req.setUserTagsFacets(true);
req.addDateCreationFacets(facettedRanges);
return req;
}
void assertDoc1FacettingResult(ApiSearchResponse res) {
assertThat(res.getDocuments().size()).isEqualTo(1);
assertThat(res.getDocumentTypeFacets().get().getCounts()).hasSize(1);
assertThat(res.getSenderNameFacets().get().getCounts()).hasSize(1);
assertThat(res.getSenderTagsFacets().get().getCounts()).hasSize(2);
assertThat(res.getUserTagsFacets().get().getCounts()).hasSize(3);
assertThat(res.getDateCreationFacets().get().getCounts()).isEqualTo( computeExpectedDateFacettingResult( Arrays.asList(doc1),facettedRanges) );
}
void assertDoc2FacettingResult(ApiSearchResponse res) {
assertThat(res.getDocuments().size()).isEqualTo(1);
assertThat(res.getDocumentTypeFacets().get().getCounts()).hasSize(1);
assertThat(res.getSenderNameFacets().get().getCounts()).hasSize(1);
assertThat(res.getSenderTagsFacets().get().getCounts()).hasSize(1);
assertThat(res.getUserTagsFacets().get().getCounts()).hasSize(1);
assertThat(res.getDateCreationFacets().get().getCounts()).isEqualTo( computeExpectedDateFacettingResult( Arrays.asList(doc2),facettedRanges) );
}
}
TestUtils utils = new TestUtils();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// when
ApiSearchRequest req = utils.baseFacettingRequest(userId);
ApiSearchResponse res = documentSearchService.search(req);
// then
assertThat(res.getDocuments().size()).isEqualTo(2);
assertThat(res.getDocumentTypeFacets().get().getCounts()).hasSize(2);
assertThat(res.getSenderNameFacets().get().getCounts()).hasSize(2);
assertThat(res.getSenderTagsFacets().get().getCounts()).hasSize(3);
assertThat(res.getUserTagsFacets().get().getCounts()).hasSize(4);
assertThat(res.getDateCreationFacets().get().getCounts()).isEqualTo( computeExpectedDateFacettingResult( Arrays.asList(doc1,doc2),facettedRanges) );
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// when
req = utils.baseFacettingRequest(userId);
req.addLocation(DocumentLocation.SAFE);
res = documentSearchService.search(req);
// then
utils.assertDoc2FacettingResult(res);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// when
req = utils.baseFacettingRequest(userId);
req.addUserTag("UserTag1");
res = documentSearchService.search(req);
// then
utils.assertDoc1FacettingResult(res);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// when
req = utils.baseFacettingRequest(userId);
req.addSenderTag("SenderTag2");
res = documentSearchService.search(req);
// then
utils.assertDoc2FacettingResult(res);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// when
req = utils.baseFacettingRequest(userId);
req.setDocumentType("Type1");
res = documentSearchService.search(req);
// then
utils.assertDoc1FacettingResult(res);
}
In this real-life exemple, I could have done a regular inner class, but someone could have been tempted to reuse it in other tests, while it was not designed to.
By the way, you will notice the ability to "capture" the dataset build in the test directly inside the utility class. Using a regular inner class, it couldn't work without creating the test specific dataset outside the test too... so you end up with a lot of things shared with other tests, while they are used (should be used) by only one.
In the end, I don't think a feature permitting to reduce the visibility is useless.
You can build a perfectly working application without using encapsulation at all, and can argue the same thing, saying the private modifier is useless...
But yes, the private modifier is certainly more useful than method local innerclasses ;)
package dto;
public class Outer {
public void method(int x, int y){
abstract class Inner{
abstract void performAction(int x,int y);
}
class InnnerA extends Inner{
#Override
void performAction(int x,int y) {
int z =x+y;
System.out.println("addition :" + z);
}
}
class InnnerB extends Inner{
#Override
void performAction(int x,int y) {
System.out.println("multiply :"+x*y);
}
}
Inner inner1 = new InnnerA();
inner1.performAction(x,y);
Inner inner2 = new InnnerB();
inner2.performAction(x,y);
}
public static void main(String args[]){
Outer outer = new Outer();
outer.method(10,20);
}
}
You can use it like this.
Related
I know that this refers to a current object. But I do not know when I really need to use it. For example, will be there any difference if I use x instead of this.x in some of the methods? May be x will refer to a variable which is local for the considered method? I mean variable which is seen only in this method.
What about this.method()? Can I use it? Should I use it. If I just use method(), will it not be, by default, applied to the current object?
The this keyword is primarily used in three situations. The first and most common is in setter methods to disambiguate variable references. The second is when there is a need to pass the current class instance as an argument to a method of another object. The third is as a way to call alternate constructors from within a constructor.
Case 1: Using this to disambiguate variable references. In Java setter methods, we commonly pass in an argument with the same name as the private member variable we are attempting to set. We then assign the argument x to this.x. This makes it clear that you are assigning the value of the parameter "name" to the instance variable "name".
public class Foo
{
private String name;
public void setName(String name) {
this.name = name;
}
}
Case 2: Using this as an argument passed to another object.
public class Foo
{
public String useBarMethod() {
Bar theBar = new Bar();
return theBar.barMethod(this);
}
public String getName() {
return "Foo";
}
}
public class Bar
{
public void barMethod(Foo obj) {
obj.getName();
}
}
Case 3: Using this to call alternate constructors. In the comments, trinithis correctly pointed out another common use of this. When you have multiple constructors for a single class, you can use this(arg0, arg1, ...) to call another constructor of your choosing, provided you do so in the first line of your constructor.
class Foo
{
public Foo() {
this("Some default value for bar");
//optional other lines
}
public Foo(String bar) {
// Do something with bar
}
}
I have also seen this used to emphasize the fact that an instance variable is being referenced (sans the need for disambiguation), but that is a rare case in my opinion.
The second important use of this (beside hiding with a local variable as many answers already say) is when accessing an outer instance from a nested non-static class:
public class Outer {
protected int a;
public class Inner {
protected int a;
public int foo(){
return Outer.this.a;
}
public Outer getOuter(){
return Outer.this;
}
}
}
You only need to use this - and most people only use it - when there's an overlapping local variable with the same name. (Setter methods, for example.)
Of course, another good reason to use this is that it causes intellisense to pop up in IDEs :)
The only need to use the this. qualifier is when another variable within the current scope shares the same name and you want to refer to the instance member (like William describes). Apart from that, there's no difference in behavior between x and this.x.
"this" is also useful when calling one constructor from another:
public class MyClass {
public MyClass(String foo) {
this(foo, null);
}
public MyClass(String foo, String bar) {
...
}
}
There are a lot of good answers, but there is another very minor reason to put this everywhere. If you have tried opening your source codes from a normal text editor (e.g. notepad etc), using this will make it a whole lot clearer to read.
Imagine this:
public class Hello {
private String foo;
// Some 10k lines of codes
private String getStringFromSomewhere() {
// ....
}
// More codes
public class World {
private String bar;
// Another 10k lines of codes
public void doSomething() {
// More codes
foo = "FOO";
// More codes
String s = getStringFromSomewhere();
// More codes
bar = s;
}
}
}
This is very clear to read with any modern IDE, but this will be a total nightmare to read with a regular text editor.
You will struggle to find out where foo resides, until you use the editor's "find" function. Then you will scream at getStringFromSomewhere() for the same reason. Lastly, after you have forgotten what s is, that bar = s is going to give you the final blow.
Compare it to this:
public void doSomething() {
// More codes
Hello.this.foo = "FOO";
// More codes
String s = Hello.this.getStringFromSomewhere();
// More codes
this.bar = s;
}
You know foo is a variable declared in outer class Hello.
You know getStringFromSomewhere() is a method declared in outer class as well.
You know that bar belongs to World class, and s is a local variable declared in that method.
Of course, whenever you design something, you create rules. So while designing your API or project, if your rules include "if someone opens all these source codes with a notepad, he or she should shoot him/herself in the head," then you are totally fine not to do this.
this is useful in the builder pattern.
public class User {
private String firstName;
private String surname;
public User(Builder builder){
firstName = builder.firstName;
surname = builder.surname;
}
public String getFirstName(){
return firstName;
}
public String getSurname(){
return surname;
}
public static class Builder {
private String firstName;
private String surname;
public Builder setFirstName(String firstName) {
this.firstName = firstName;
return this;
}
public Builder setSurname(String surname) {
this.surname = surname;
return this;
}
public User build(){
return new User(this);
}
}
public static void main(String[] args) {
User.Builder builder = new User.Builder();
User user = builder.setFirstName("John").setSurname("Doe").build();
}
}
Unless you have overlapping variable names, its really just for clarity when you're reading the code.
#William Brendel answer provided three different use cases in nice way.
Use case 1:
Offical java documentation page on this provides same use-cases.
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.
It covers two examples :
Using this with a Field and Using this with a Constructor
Use case 2:
Other use case which has not been quoted in this post: this can be used to synchronize the current object in a multi-threaded application to guard critical section of data & methods.
synchronized(this){
// Do some thing.
}
Use case 3:
Implementation of Builder pattern depends on use of this to return the modified object.
Refer to this post
Keeping builder in separate class (fluent interface)
Google turned up a page on the Sun site that discusses this a bit.
You're right about the variable; this can indeed be used to differentiate a method variable from a class field.
private int x;
public void setX(int x) {
this.x=x;
}
However, I really hate that convention. Giving two different variables literally identical names is a recipe for bugs. I much prefer something along the lines of:
private int x;
public void setX(int newX) {
x=newX;
}
Same results, but with no chance of a bug where you accidentally refer to x when you really meant to be referring to x instead.
As to using it with a method, you're right about the effects; you'll get the same results with or without it. Can you use it? Sure. Should you use it? Up to you, but given that I personally think it's pointless verbosity that doesn't add any clarity (unless the code is crammed full of static import statements), I'm not inclined to use it myself.
Following are the ways to use ‘this’ keyword in java :
Using this keyword to refer current class instance variables
Using this() to invoke current class constructor
Using this keyword to return the current class instance
Using this keyword as method parameter
https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
when there are two variables one instance variable and other local variable of the same name then we use this. to refer current executing object to avoid the conflict between the names.
this is a reference to the current object. It is used in the constructor to distinguish between the local and the current class variable which have the same name. e.g.:
public class circle {
int x;
circle(int x){
this.x =x;
//class variable =local variable
}
}
this can also be use to call one constructor from another constructor. e.g.:
public class circle {
int x;
circle() {
this(1);
}
circle(int x) {
this.x = x;
}
}
Will be there any difference if I use "x" instead of "this.x" in some of the methods?
Usually not. But it makes a difference sometimes:
class A {
private int i;
public A(int i) {
this.i = i; // this.i can be used to disambiguate the i being referred to
}
}
If I just use "method()", will it not be, by default, applied to the current object?
Yes. But if needed, this.method() clarifies that the call is made by this object.
this does not affect resulting code - it is compilation time operator and the code generated with or without it will be the same. When you have to use it, depends on context. For example you have to use it, as you said, when you have local variable that shadows class variable and you want refer to class variable and not local one.
edit: by "resulting code will be the same" I mean of course, when some variable in local scope doesn't hide the one belonging to class. Thus
class POJO {
protected int i;
public void modify() {
i = 9;
}
public void thisModify() {
this.i = 9;
}
}
resulting code of both methods will be the same. The difference will be if some method declares local variable with the same name
public void m() {
int i;
i = 9; // i refers to variable in method's scope
this.i = 9; // i refers to class variable
}
With respect to William Brendel's posts and dbconfessions question, regarding case 2. Here is an example:
public class Window {
private Window parent;
public Window (Window parent) {
this.parent = parent;
}
public void addSubWindow() {
Window child = new Window(this);
list.add(child);
}
public void printInfo() {
if (parent == null) {
System.out.println("root");
} else {
System.out.println("child");
}
}
}
I've seen this used, when building parent-child relation's with objects. However, please note that it is simplified for the sake of brevity.
To make sure that the current object's members are used. Cases where thread safety is a concern, some applications may change the wrong objects member values, for that reason this should be applied to the member so that the correct object member value is used.
If your object is not concerned with thread safety then there is no reason to specify which object member's value is used.
I know that this refers to a current object. But I do not know when I really need to use it. For example, will be there any difference if I use x instead of this.x in some of the methods? May be x will refer to a variable which is local for the considered method? I mean variable which is seen only in this method.
What about this.method()? Can I use it? Should I use it. If I just use method(), will it not be, by default, applied to the current object?
The this keyword is primarily used in three situations. The first and most common is in setter methods to disambiguate variable references. The second is when there is a need to pass the current class instance as an argument to a method of another object. The third is as a way to call alternate constructors from within a constructor.
Case 1: Using this to disambiguate variable references. In Java setter methods, we commonly pass in an argument with the same name as the private member variable we are attempting to set. We then assign the argument x to this.x. This makes it clear that you are assigning the value of the parameter "name" to the instance variable "name".
public class Foo
{
private String name;
public void setName(String name) {
this.name = name;
}
}
Case 2: Using this as an argument passed to another object.
public class Foo
{
public String useBarMethod() {
Bar theBar = new Bar();
return theBar.barMethod(this);
}
public String getName() {
return "Foo";
}
}
public class Bar
{
public void barMethod(Foo obj) {
obj.getName();
}
}
Case 3: Using this to call alternate constructors. In the comments, trinithis correctly pointed out another common use of this. When you have multiple constructors for a single class, you can use this(arg0, arg1, ...) to call another constructor of your choosing, provided you do so in the first line of your constructor.
class Foo
{
public Foo() {
this("Some default value for bar");
//optional other lines
}
public Foo(String bar) {
// Do something with bar
}
}
I have also seen this used to emphasize the fact that an instance variable is being referenced (sans the need for disambiguation), but that is a rare case in my opinion.
The second important use of this (beside hiding with a local variable as many answers already say) is when accessing an outer instance from a nested non-static class:
public class Outer {
protected int a;
public class Inner {
protected int a;
public int foo(){
return Outer.this.a;
}
public Outer getOuter(){
return Outer.this;
}
}
}
You only need to use this - and most people only use it - when there's an overlapping local variable with the same name. (Setter methods, for example.)
Of course, another good reason to use this is that it causes intellisense to pop up in IDEs :)
The only need to use the this. qualifier is when another variable within the current scope shares the same name and you want to refer to the instance member (like William describes). Apart from that, there's no difference in behavior between x and this.x.
"this" is also useful when calling one constructor from another:
public class MyClass {
public MyClass(String foo) {
this(foo, null);
}
public MyClass(String foo, String bar) {
...
}
}
There are a lot of good answers, but there is another very minor reason to put this everywhere. If you have tried opening your source codes from a normal text editor (e.g. notepad etc), using this will make it a whole lot clearer to read.
Imagine this:
public class Hello {
private String foo;
// Some 10k lines of codes
private String getStringFromSomewhere() {
// ....
}
// More codes
public class World {
private String bar;
// Another 10k lines of codes
public void doSomething() {
// More codes
foo = "FOO";
// More codes
String s = getStringFromSomewhere();
// More codes
bar = s;
}
}
}
This is very clear to read with any modern IDE, but this will be a total nightmare to read with a regular text editor.
You will struggle to find out where foo resides, until you use the editor's "find" function. Then you will scream at getStringFromSomewhere() for the same reason. Lastly, after you have forgotten what s is, that bar = s is going to give you the final blow.
Compare it to this:
public void doSomething() {
// More codes
Hello.this.foo = "FOO";
// More codes
String s = Hello.this.getStringFromSomewhere();
// More codes
this.bar = s;
}
You know foo is a variable declared in outer class Hello.
You know getStringFromSomewhere() is a method declared in outer class as well.
You know that bar belongs to World class, and s is a local variable declared in that method.
Of course, whenever you design something, you create rules. So while designing your API or project, if your rules include "if someone opens all these source codes with a notepad, he or she should shoot him/herself in the head," then you are totally fine not to do this.
this is useful in the builder pattern.
public class User {
private String firstName;
private String surname;
public User(Builder builder){
firstName = builder.firstName;
surname = builder.surname;
}
public String getFirstName(){
return firstName;
}
public String getSurname(){
return surname;
}
public static class Builder {
private String firstName;
private String surname;
public Builder setFirstName(String firstName) {
this.firstName = firstName;
return this;
}
public Builder setSurname(String surname) {
this.surname = surname;
return this;
}
public User build(){
return new User(this);
}
}
public static void main(String[] args) {
User.Builder builder = new User.Builder();
User user = builder.setFirstName("John").setSurname("Doe").build();
}
}
Unless you have overlapping variable names, its really just for clarity when you're reading the code.
#William Brendel answer provided three different use cases in nice way.
Use case 1:
Offical java documentation page on this provides same use-cases.
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.
It covers two examples :
Using this with a Field and Using this with a Constructor
Use case 2:
Other use case which has not been quoted in this post: this can be used to synchronize the current object in a multi-threaded application to guard critical section of data & methods.
synchronized(this){
// Do some thing.
}
Use case 3:
Implementation of Builder pattern depends on use of this to return the modified object.
Refer to this post
Keeping builder in separate class (fluent interface)
Google turned up a page on the Sun site that discusses this a bit.
You're right about the variable; this can indeed be used to differentiate a method variable from a class field.
private int x;
public void setX(int x) {
this.x=x;
}
However, I really hate that convention. Giving two different variables literally identical names is a recipe for bugs. I much prefer something along the lines of:
private int x;
public void setX(int newX) {
x=newX;
}
Same results, but with no chance of a bug where you accidentally refer to x when you really meant to be referring to x instead.
As to using it with a method, you're right about the effects; you'll get the same results with or without it. Can you use it? Sure. Should you use it? Up to you, but given that I personally think it's pointless verbosity that doesn't add any clarity (unless the code is crammed full of static import statements), I'm not inclined to use it myself.
Following are the ways to use ‘this’ keyword in java :
Using this keyword to refer current class instance variables
Using this() to invoke current class constructor
Using this keyword to return the current class instance
Using this keyword as method parameter
https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
when there are two variables one instance variable and other local variable of the same name then we use this. to refer current executing object to avoid the conflict between the names.
this is a reference to the current object. It is used in the constructor to distinguish between the local and the current class variable which have the same name. e.g.:
public class circle {
int x;
circle(int x){
this.x =x;
//class variable =local variable
}
}
this can also be use to call one constructor from another constructor. e.g.:
public class circle {
int x;
circle() {
this(1);
}
circle(int x) {
this.x = x;
}
}
Will be there any difference if I use "x" instead of "this.x" in some of the methods?
Usually not. But it makes a difference sometimes:
class A {
private int i;
public A(int i) {
this.i = i; // this.i can be used to disambiguate the i being referred to
}
}
If I just use "method()", will it not be, by default, applied to the current object?
Yes. But if needed, this.method() clarifies that the call is made by this object.
this does not affect resulting code - it is compilation time operator and the code generated with or without it will be the same. When you have to use it, depends on context. For example you have to use it, as you said, when you have local variable that shadows class variable and you want refer to class variable and not local one.
edit: by "resulting code will be the same" I mean of course, when some variable in local scope doesn't hide the one belonging to class. Thus
class POJO {
protected int i;
public void modify() {
i = 9;
}
public void thisModify() {
this.i = 9;
}
}
resulting code of both methods will be the same. The difference will be if some method declares local variable with the same name
public void m() {
int i;
i = 9; // i refers to variable in method's scope
this.i = 9; // i refers to class variable
}
With respect to William Brendel's posts and dbconfessions question, regarding case 2. Here is an example:
public class Window {
private Window parent;
public Window (Window parent) {
this.parent = parent;
}
public void addSubWindow() {
Window child = new Window(this);
list.add(child);
}
public void printInfo() {
if (parent == null) {
System.out.println("root");
} else {
System.out.println("child");
}
}
}
I've seen this used, when building parent-child relation's with objects. However, please note that it is simplified for the sake of brevity.
To make sure that the current object's members are used. Cases where thread safety is a concern, some applications may change the wrong objects member values, for that reason this should be applied to the member so that the correct object member value is used.
If your object is not concerned with thread safety then there is no reason to specify which object member's value is used.
This question already has answers here:
Is there a way to simulate the C++ 'friend' concept in Java?
(18 answers)
Closed 8 years ago.
How does one implement the friend concept in Java (like C++)?
Java does not have the friend keyword from C++. There is, however, a way to emulate that; a way that actually gives a lot more precise control. Suppose that you have classes A and B. B needs access to some private method or field in A.
public class A {
private int privateInt = 31415;
public class SomePrivateMethods {
public int getSomethingPrivate() { return privateInt; }
private SomePrivateMethods() { } // no public constructor
}
public void giveKeyTo(B other) {
other.receiveKey(new SomePrivateMethods());
}
}
public class B {
private A.SomePrivateMethods key;
public void receiveKey(A.SomePrivateMethods key) {
this.key = key;
}
public void usageExample() {
A anA = new A();
// int foo = anA.privateInt; // doesn't work, not accessible
anA.giveKeyTo(this);
int fii = key.getSomethingPrivate();
System.out.println(fii);
}
}
The usageExample() shows how this works. The instance of B doesn't have access to the private fields or methods of an instance of A. But by calling the giveKeyTo(), class B can get access. No other class can get access to that method, since it a requires a valid B as an argument. The constructor is private.
The class B can then use any of the methods that are handed to it in the key. This, while clumsier to set up than the C++ friend keyword, is much more fine-grained. The class A can chose exactly which methods to expose to exactly which classes.
Now, in the above case A is granting access to all instances of B and instances of subclasses of B. If the latter is not desired, then the giveKeyTo() method can internally check the exact type of other with getClass(), and throw an exception if it is not precisely B.
Suppose A.foo() should only be called by B. This can be arranged by a token that can only be generated by B.
public class B
{
public static class ToA { private ToA(){} }
private static final ToA b2a = new ToA();
void test()
{
new A().foo(b2a);
}
}
public class A
{
public void foo(B.ToA b2a)
{
if(b2a==null)
throw new Error("you ain't B");
// ...
}
}
Only B can generate a non-null B.ToA token. If both A and B do not leak this token to the 3rd party,
nobody else can invoke A.foo()
If A2 wants to friend B too, it needs a different token type. If it's the same token type, since A got a token of the type from B, A can pretend to be B to A2.
The check is done at runtime, not compile time, that is not perfect. Not a big deal though, since any 3rd party can only invoke A.foo() with a null, it can't be an innocent mistake which we want to check at compile time; it's probably malicious so we don't care to warn the caller at compile time.
In Java you can put both (or more) classes into the same package. All methods and fields with the protected qualifier can directly be accessed by all classes in that package.
I figured out another way to achieve the same. Basically you check the fully qualified name of the invoking class name. If it matches your "friend" function, then you give access, else you return null.
public class A {
private static int privateInt = 31415;
public static int getPrivateInt() {
if(Throwable().getStackTrace()[1].getClassName().equals(new String("example.java.testing.B")))
{
return privateInt;
}
else
{
return null;
}
}
}
package example.java.testing;
public class B {
public void usageExample() {
int foo = A.getPrivateInt; // works only for B
System.out.println(foo);
}
}
I have come across a bit of a problem. I have a class called "GameScreen" which will know what level and stage has been selected. From that I can build a string to suggest something like "level1_1" or "level1_2". The problem is how do I load this class now?
I was going to use Class.forname(string) however each level is a different class so how do I pass the new operator to the class?
I am trying to achieve something like this... world = new World(worldListener); where "World" is the class such as "level1_1".
Hope that makes sense.
Aside from the fact that there are much better ways to implement this (see the other answers, for example), this should work (not tested, ignores exceptions, may cause abdominal distention, etc.):
public World createWorld(String levelClassName, WorldListener listener) throws Exception
{
Class<?> clazz = Class.forName(name);
Constructor<World> ctor = (Constructor<World>) clazz.getConstructor(WorldListener.class);
World world = ctor.newInstance(listener);
return world;
}
You must use reflection (java.lang.reflect)
First, even if the class for each level is different, all of them should extend/implement a common superclass/interface so basic operations are available (v.g. a constructor, a startLevel() method, and so on).
With reflection, you can chose the class related to your level, instantiate it, and pass it to your engine so it invokes your class.
As a side note, I find the architecture strange. Unless there is some other reason to do this, I would suggest using a unique class for levels and loading the configuration for each level from files. It may not be suited if gameplay changes between level, though.
See the Factory Pattern. For your case you could implement a CreateLevel(String level) method which does a simple case-statement to determine which class to create or use reflection.
Um... there's 101 better ways of doing that.
Update For example:
public abstract class Level {
// or whatever your interface is
abstract public void createWorld(WorldListener worldListener);
abstract public void nextWorld();
}
public class Level1 extends Level {
public void createLevel(WorldListener worldListener) {
/** do it **/
}
public Level nextLevel() { return new Level2(); }
}
Then somewhere else:
Level cur = new Level1();
do {
cur.createLevel(worldListener);
...
cur = cur.nextLevel();
} while (cur != null);
Original
For example:
public abstract class Level {
final public int number;
public Level(int num) { this.number = num; levels[num-1] = this;/* set up level */ }
// adjust 10 to number of levels
static private Level[] = new Level[10];
static public getLevel(int num) { return levels[num-1]; }
// or whatever your interface is
abstract public void createWorld(WorldListener worldListener);
}
public class Level1 extends Level {
public Level1() { super(0); }
public void createWorld(WorldListener worldListener) {
/** do it **/
}
}
Then somewhere else:
Level.getLevel(1).createWorld();
I know that this refers to a current object. But I do not know when I really need to use it. For example, will be there any difference if I use x instead of this.x in some of the methods? May be x will refer to a variable which is local for the considered method? I mean variable which is seen only in this method.
What about this.method()? Can I use it? Should I use it. If I just use method(), will it not be, by default, applied to the current object?
The this keyword is primarily used in three situations. The first and most common is in setter methods to disambiguate variable references. The second is when there is a need to pass the current class instance as an argument to a method of another object. The third is as a way to call alternate constructors from within a constructor.
Case 1: Using this to disambiguate variable references. In Java setter methods, we commonly pass in an argument with the same name as the private member variable we are attempting to set. We then assign the argument x to this.x. This makes it clear that you are assigning the value of the parameter "name" to the instance variable "name".
public class Foo
{
private String name;
public void setName(String name) {
this.name = name;
}
}
Case 2: Using this as an argument passed to another object.
public class Foo
{
public String useBarMethod() {
Bar theBar = new Bar();
return theBar.barMethod(this);
}
public String getName() {
return "Foo";
}
}
public class Bar
{
public void barMethod(Foo obj) {
obj.getName();
}
}
Case 3: Using this to call alternate constructors. In the comments, trinithis correctly pointed out another common use of this. When you have multiple constructors for a single class, you can use this(arg0, arg1, ...) to call another constructor of your choosing, provided you do so in the first line of your constructor.
class Foo
{
public Foo() {
this("Some default value for bar");
//optional other lines
}
public Foo(String bar) {
// Do something with bar
}
}
I have also seen this used to emphasize the fact that an instance variable is being referenced (sans the need for disambiguation), but that is a rare case in my opinion.
The second important use of this (beside hiding with a local variable as many answers already say) is when accessing an outer instance from a nested non-static class:
public class Outer {
protected int a;
public class Inner {
protected int a;
public int foo(){
return Outer.this.a;
}
public Outer getOuter(){
return Outer.this;
}
}
}
You only need to use this - and most people only use it - when there's an overlapping local variable with the same name. (Setter methods, for example.)
Of course, another good reason to use this is that it causes intellisense to pop up in IDEs :)
The only need to use the this. qualifier is when another variable within the current scope shares the same name and you want to refer to the instance member (like William describes). Apart from that, there's no difference in behavior between x and this.x.
"this" is also useful when calling one constructor from another:
public class MyClass {
public MyClass(String foo) {
this(foo, null);
}
public MyClass(String foo, String bar) {
...
}
}
There are a lot of good answers, but there is another very minor reason to put this everywhere. If you have tried opening your source codes from a normal text editor (e.g. notepad etc), using this will make it a whole lot clearer to read.
Imagine this:
public class Hello {
private String foo;
// Some 10k lines of codes
private String getStringFromSomewhere() {
// ....
}
// More codes
public class World {
private String bar;
// Another 10k lines of codes
public void doSomething() {
// More codes
foo = "FOO";
// More codes
String s = getStringFromSomewhere();
// More codes
bar = s;
}
}
}
This is very clear to read with any modern IDE, but this will be a total nightmare to read with a regular text editor.
You will struggle to find out where foo resides, until you use the editor's "find" function. Then you will scream at getStringFromSomewhere() for the same reason. Lastly, after you have forgotten what s is, that bar = s is going to give you the final blow.
Compare it to this:
public void doSomething() {
// More codes
Hello.this.foo = "FOO";
// More codes
String s = Hello.this.getStringFromSomewhere();
// More codes
this.bar = s;
}
You know foo is a variable declared in outer class Hello.
You know getStringFromSomewhere() is a method declared in outer class as well.
You know that bar belongs to World class, and s is a local variable declared in that method.
Of course, whenever you design something, you create rules. So while designing your API or project, if your rules include "if someone opens all these source codes with a notepad, he or she should shoot him/herself in the head," then you are totally fine not to do this.
this is useful in the builder pattern.
public class User {
private String firstName;
private String surname;
public User(Builder builder){
firstName = builder.firstName;
surname = builder.surname;
}
public String getFirstName(){
return firstName;
}
public String getSurname(){
return surname;
}
public static class Builder {
private String firstName;
private String surname;
public Builder setFirstName(String firstName) {
this.firstName = firstName;
return this;
}
public Builder setSurname(String surname) {
this.surname = surname;
return this;
}
public User build(){
return new User(this);
}
}
public static void main(String[] args) {
User.Builder builder = new User.Builder();
User user = builder.setFirstName("John").setSurname("Doe").build();
}
}
Unless you have overlapping variable names, its really just for clarity when you're reading the code.
#William Brendel answer provided three different use cases in nice way.
Use case 1:
Offical java documentation page on this provides same use-cases.
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.
It covers two examples :
Using this with a Field and Using this with a Constructor
Use case 2:
Other use case which has not been quoted in this post: this can be used to synchronize the current object in a multi-threaded application to guard critical section of data & methods.
synchronized(this){
// Do some thing.
}
Use case 3:
Implementation of Builder pattern depends on use of this to return the modified object.
Refer to this post
Keeping builder in separate class (fluent interface)
Google turned up a page on the Sun site that discusses this a bit.
You're right about the variable; this can indeed be used to differentiate a method variable from a class field.
private int x;
public void setX(int x) {
this.x=x;
}
However, I really hate that convention. Giving two different variables literally identical names is a recipe for bugs. I much prefer something along the lines of:
private int x;
public void setX(int newX) {
x=newX;
}
Same results, but with no chance of a bug where you accidentally refer to x when you really meant to be referring to x instead.
As to using it with a method, you're right about the effects; you'll get the same results with or without it. Can you use it? Sure. Should you use it? Up to you, but given that I personally think it's pointless verbosity that doesn't add any clarity (unless the code is crammed full of static import statements), I'm not inclined to use it myself.
Following are the ways to use ‘this’ keyword in java :
Using this keyword to refer current class instance variables
Using this() to invoke current class constructor
Using this keyword to return the current class instance
Using this keyword as method parameter
https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
when there are two variables one instance variable and other local variable of the same name then we use this. to refer current executing object to avoid the conflict between the names.
this is a reference to the current object. It is used in the constructor to distinguish between the local and the current class variable which have the same name. e.g.:
public class circle {
int x;
circle(int x){
this.x =x;
//class variable =local variable
}
}
this can also be use to call one constructor from another constructor. e.g.:
public class circle {
int x;
circle() {
this(1);
}
circle(int x) {
this.x = x;
}
}
Will be there any difference if I use "x" instead of "this.x" in some of the methods?
Usually not. But it makes a difference sometimes:
class A {
private int i;
public A(int i) {
this.i = i; // this.i can be used to disambiguate the i being referred to
}
}
If I just use "method()", will it not be, by default, applied to the current object?
Yes. But if needed, this.method() clarifies that the call is made by this object.
this does not affect resulting code - it is compilation time operator and the code generated with or without it will be the same. When you have to use it, depends on context. For example you have to use it, as you said, when you have local variable that shadows class variable and you want refer to class variable and not local one.
edit: by "resulting code will be the same" I mean of course, when some variable in local scope doesn't hide the one belonging to class. Thus
class POJO {
protected int i;
public void modify() {
i = 9;
}
public void thisModify() {
this.i = 9;
}
}
resulting code of both methods will be the same. The difference will be if some method declares local variable with the same name
public void m() {
int i;
i = 9; // i refers to variable in method's scope
this.i = 9; // i refers to class variable
}
With respect to William Brendel's posts and dbconfessions question, regarding case 2. Here is an example:
public class Window {
private Window parent;
public Window (Window parent) {
this.parent = parent;
}
public void addSubWindow() {
Window child = new Window(this);
list.add(child);
}
public void printInfo() {
if (parent == null) {
System.out.println("root");
} else {
System.out.println("child");
}
}
}
I've seen this used, when building parent-child relation's with objects. However, please note that it is simplified for the sake of brevity.
To make sure that the current object's members are used. Cases where thread safety is a concern, some applications may change the wrong objects member values, for that reason this should be applied to the member so that the correct object member value is used.
If your object is not concerned with thread safety then there is no reason to specify which object member's value is used.