Why 'this' is not allowed in static methods? - java

I know this represents the object invoking the method and static methods are not bound to any object but my question is still you can invoke static method on class object .
Why java has made this thing available and not for this ?

this points to the current instance of the class.
Static methods are associated with a class, not an instance, so there's nothing for this to point to.
Here's an example:
public class Foo {
private String name;
public static void someClassMethod() { System.out.println("associated with a class"); }
public Foo(String n) { this.name = n; }
public String getName() { return this.name; }
public void setName(String n) { this.name = n; }
public void doAnotherThing() {
Foo.someClassMethod(); // This is what is really happening when you call a static method in an non-static method.
}
}

Simple answer: this is not defined outside of a non-static method.
Calling static methods on an instance is a syntactic shorthand, which I don't agree should exist.

From every point of view this always means this object, so giving possibility for meaning this class could lead to multiple bugs

The difference here is between a class and an object. A non-static method is called on an object, while a static method is Called on a class.
You can see a Class as a blueprint, with which Objects are built.
A class House has a static method hasDoor() (which will return true), while an object of the type House can have a method openDoor(). You can't open the door of a blueprint.
One can call House.hasDoor(), but not House.openDoor(). One can call
House h = new House();
h.openDoor();
While you can call h.hasDoor(), this is a bit nasty and should be avoided in most cases

Related

Surprising access to fields with Java anonymous class

I'm trying to better understand the concept of anonymous classes in Java. From other answers on this website, I learned that an anonymous class can access non-final fields of the enclosing class using OuterClass.this.myField.
I made the following simple test case with an interface, AnonInt, and a class AnonTest with a method foo which returns an instance of an anonymous class implementing AnonInt. Dspite the fact that I'm using System.out.println(a) rather than System.out.println(AnonTest.this.a) the code works and prints the correct result. How can this be?
public interface AnonInt {
void print();
}
public class AnonTest {
private int a;
public AnonTest(int a) {
this.a = a;
}
public AnonInt foo() {
return new AnonInt() {
public void print() {
System.out.println(a);
}
};
}
public static void main(String[] args) {
AnonTest at = new AnonTest(37);
AnonInt ai = at.foo();
ai.print();
}
}
Despite the fact that I'm using System.out.println(a) rather than System.out.println(AnonTest.this.a) the code works and prints the correct result. How can this be?
Since the reference to a is unambiguous in your context, the two expressions reference the same field.
Generally, AnonTest.this is required in a very specific context - when your method needs to access AnonTest object itself, rather than accessing one of its members. In case of your program, this is unnecessary: the compiler resolves the expression a to the object AnonTest.this.a, and passes it to System.out.println.

overriding protected method of Superclass

In the below example why does the String b prints null and String c prints "gg".
Correct me if I am wrong, whenever a subclass (BClass) overrides a protected method (i.e initClass()) of the superclass (AClass).If you instantiate the subclass. The superclass must make use of overriden method specified by the subclass.
public class Example {
public class AClass {
private String a;
public AClass() {
initClass();
}
protected void initClass() {
a = "randomtext";
}
}
public class BClass extends AClass {
private String b = null;
private String c;
#Override
protected void initClass() {
b = "omg!";
c = "gg";
}
public void bValue() {
System.out.println(b); // prints null
System.out.println(c); // prints "gg"
}
}
public static void main(String[] args) {
Example.BClass b = new Example().new BClass();
b.bValue();
}
}
As of the JSF 12.5
In the example you can see the execution order. The first steps are the callings of the Constructor down to the Object constructor.
Afterwards this happens:
Next, all initializers for the instance variables of class [...] are executed.
Since your instance variable b is initialized to null it will be null again afterwards
This is happening because the superclass constructor is called before the fields of ClassB is initialized. Hence the initClass() method is called which sets b = "omg!" but then again when the super class constructor returns, b is initialized to the value declared in ClassB which is null.
To debug, put a break point and go step by step, you will find that b is first set to null and then changes to omg! and then comes back to null.
There have been already given several correct answers about what's happening. I just wanted to add that it is generally bad practice to call overridden methods from constructor (except of course if you know exactly what you are doing). As you can see, the subclass may not be completely initialised at the time its instance method is invoked (subclass constructor logic has not been executed yet, so effectively overridden method is invoked on an unconstructed object which is dangerous) which might lead to confusions like the one described in this question.
It is much better to write initialisation logic in the constructor and if it is too long then divide it between several private methods invoked from the constructor.
This is happening like this because, first constructor of AClass, which set value of b = omg! and c=gg. After that When BClass gets load in memory it set b=null and c remain as it is which is gg, this is happening because, because in BClass, for b you are doing declaration as well as initialization and for c you are doing only declaration, so as c is already in the memory it even won't get it's default value and as you are not doing any initialization for c, it remain with it's earlier state.
I believe that this example explains the issue:
public class Main {
private static class PrintOnCreate {
public PrintOnCreate(String message) {
System.out.println(message);
}
}
private static class BaseClass {
private PrintOnCreate member =
new PrintOnCreate("BaseClass: member initialization");
static {
System.out.println("BaseClass: static initialization");
}
public BaseClass() {
System.out.println("BaseClass: constructor");
memberCalledFromConstructor();
}
public void memberCalledFromConstructor() {
System.out.println("BaseClass: member called from constructor");
}
}
private static class DerivedClass extends BaseClass {
private PrintOnCreate member =
new PrintOnCreate("DerivedClass: member initialization");
static {
System.out.println("DerivedClass: static initialization");
}
public DerivedClass() {
System.out.println("DerivedClass: constructor");
}
#Override
public void memberCalledFromConstructor() {
System.out.println("DerivedClass: member called from constructor");
}
}
public static void main (String[] args) {
BaseClass obj = new DerivedClass();
}
}
The output from this program is:
BaseClass: static initialization
DerivedClass: static initialization
BaseClass: member initialization
BaseClass: constructor
DerivedClass: member called from constructor
DerivedClass: member initialization
DerivedClass: constructor
... which demonstrates that the derived class's members are initialized after the base class's constructor (and the invocation of the derived class's member function have completed). This also demonstrates a key danger of invoking an overridable function from a constructor, namely that the function can be invoked before the members of the class on which it depends have been initialized. For this reason, constructors should generally avoid invoking member functions (and, when they do, those functions should either be final or static, so that they either depend only on the current class which has been initialized or on none of the instance variables).

How to call function with same name from an inherited class in java

I am new to java and I remember in c++ we did something like CLASSNAME::Fn() to avoid ambiguity in inheritance.
Here's my code and I want to have same display methods in both classes and access them explicitly.
public class Main {
public static void main(String args[]){
Emplo e = new Emplo("samuel",19,"designer",465);
e.display(); // here i want to call both display()
}
}
public class Person {
String name;
int age;
Person(String s, int a){
name = s;
age = a;
}
public void dispaly(){
System.out.println("name: "+name+"\nage: "+age);
}
}
public class Emplo extends Person {
String desg;
double sal;
Emplo(String s,int a,String d, double sa){
super(s,a);
desg=d;
sal=sa;
}
void display(){
System.out.println("desg: "+desg+"\nsal: "+sal);
}
}
In java, you can't not call the specific method implementation of the class of the instance.
That is, you can't "bypass" a sub-class method and call a super-class version of the method; calling the super-class method can only be done from within the subclass using super.someMethod().
You can't even invoke a super-super class's version, ie you can't do something like super.super.someMethod()
First of in here you are use two different method. display() in Emplo and dispaly() in Person. SO there is no point of talking ambiguity or overriding make that correct.
Suppose you are corrected that. Then you can't code keep this way
public void display(){ // method in Person
System.out.println("name: "+name+"\nage: "+age);
}
Then
void display(){ // method in Emplo
System.out.println("desg: "+desg+"\nsal: "+sal);
}
You are using weaker modifier to override, So you can't compile this code. You can make public the method in Emplo.
And answer for your last question. you can't do it. can't call both method.
In the second display method call the super class display method by using super keywod as :
super.display(); (should be the first statement of the method)
and there will be no ambiguity because that display method will be called whose object is being created that means that the display() method of Employee will be called in this case
so if you want to call the display method of Person class then you should create the object of that class and reference by That class type like :
Person p = new Person(your data);
p.display() // here display method of person will be called
and No you cannot call both methods from the same reference
In your Emplo class display() method super.dispaly() indicates display() method of immediate super class i.e Person class.
void display(){ // here in Emplo class you can't give more restrictive modifier(i.e `public` to `default`. since in `Person` class it is `public` so it must be `public`.(overriding rule)
super.dispaly();
System.out.println("desg: "+desg+"\nsal: "+sal);
}
so put public modifier here:
public void display(){
super.dispaly();
System.out.println("desg: "+desg+"\nsal: "+sal);
}
`
Perhaps this answers your question:
public void myMethod()
{ //inherited method
super.myMethod(); //calls base class method
//... add more code to inherited method
}
for details see original source:
In Java, how do I call a base class's method from the overriding method in a derived class?

Example of an instance method? (Java)

I'm still learning about methods in Java and was wondering how exactly you might use an instance method. I was thinking about something like this:
public void example(String random) {
}
However, I'm not sure if this is actually an instance method or some other type of method. Could someone help me out?
If it's not a static method then it's an instance method. It's either one or the other. So yes, your method,
public void example(String random) {
// this doesn't appear to do anything
}
is an example of an instance method.
Regarding
and was wondering how exactly you might use an instance method
You would create an instance of the class, an object, and then call the instance method on the instance. i.e.,
public class Foo {
public void bar() {
System.out.println("I'm an instance method");
}
}
which could be used like:
Foo foo = new Foo(); // create an instance
foo.bar(); // call method on it
class InstanceMethod
{
public static void main(String [] args){
InstanceMethod obj = new InstanceMethod();// because that method we wrote is instance we will write an object to call it
System.out.println(obj.sum(3,2));
}
int f;
public double sum(int x,int y){// this method is instance method because we dont write static
f = x+y;
return f;
}
}
*An instance method * is a method is associated with objects, each instance method is called with a hidden argument that refers to the current object.
for example on an instance method :
public void myMethod {
// to do when call code
}
Instance method means the object of your class must be created to access the method. On the other hand, for static methods, as its a property of Class and not that of its object/instance, it is accessed without creating any instance of the class. But remember static methods can only access static variables, where as instance method can access the instance variables of your class.
Static methods and static variables are useful for memory management as it does not require to declare objects which would otherwise occupy memory.
Example of instance method and variable :
public class Example {
int a = 10; // instance variable
private static int b = 10; // static variable (belongs to the class)
public void instanceMethod(){
a =a + 10;
}
public static void staticMethod(){
b = b + 10;
}
}
void main(){
Example exmp = new Example();
exmp.instanceMethod(); // right
exmp.staticMethod(); // wrong..error..
// from here static variable and method cant be accessed.
}
Instance methods are the methods that require an object to access them where as static methods do not. The method that you mentioned is an instance method since it does not contain static keyword.
Example of instance method:
class main
{
public void instanceMethod()//instance method
{
System.out.println("Hello world");
}
}
The above method can be accessed with an object:
main obj=new main();//instance of class "main"
obj.instanceMethod();//accessing instance method using object
Hope this might help you.
Instance block with Cases { Static , constructor , Local method )
OutPut will be :

Difference between "field" and "this.field" in Java

I'd like to better understand what is the difference in referring to a class field by using this.field and field alone as in
this.integerField = 5;
and
integerField = 5;
this keyword refers to the current object.
usually we use this.memberVariable to diffrentiate between the member and local variables
private int x=10;
public void m1(int x) {
sysout(this.x)//would print 10 member variable
sysout(x); //would print 5; local variable
}
public static void main(String..args) {
new classInst().m1(5);
}
Off from the concrete question,
the use of this In Overloaded constructors:
we can use this to call overloaded constructor like below:
public class ABC {
public ABC() {
this("example");to call overloadedconstructor
sysout("no args cons");
}
public ABC(String x){
sysout("one argscons")
}
}
The use of this keywords lets you disambiguate between member variables and locals, such as function parameters:
public MyClass(int integerField) {
this.integerField = integerField;
}
The code snippet above assigns the value of local variable integerField to the member variable of the class with the same name.
Some shops adopt coding standards requiring all member accesses to be qualified with this. This is valid, but unnecessary; in cases where no collision exists, removing this does not change the semantic of your program.
When you are in an instance method, you may need to specify to which scope you refer a variable from. For example :
private int x;
public void method(int x) {
System.out.println("Method x : " + x);
System.out.println("Instance x : " + this.x);
}
While, in this example, you have two x variables, one is a local method variable and one is a class variable. You may distinguish between the two with this to specify it.
Some people always use this before using a class variable. While it is not necessary, it may improve code readability.
As for polymorphism, you may refer to the parent class as super. For example :
class A {
public int getValue() { return 1; }
}
class B extends A {
// override A.getValue()
public int getValue() { return 2; }
// return 1 from A.getValue()
// have we not used super, the method would have returned the same as this.getValue()
public int getParentValue() { return super.getValue(); }
}
Both keywords this and super depend on the scope from where you are using it; it depends on the instance (object) you are working with at run-time.
It's exactly the same. Because you often type this.xyz it's a shortcut that means the same thing if there is a field by that name and there isn't a local variable that shadows it.
Though they look and act the same, there is a difference when the same name is shared between a field and a method argument, e.g.:
private String name;
public void setName(String name){
this.name = name;
}
name is the passed parameter, and this.name is the proper class field.
Notice that typing this.... prompts you a list of all the class fields [and methods] in many IDEs.
From the Java tutorials:
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.
So, when you call a method within a object the call looks like this:
public class MyClass{
private int field;
public MyClass(){
this(10); // Will call the constructor with a int argument
}
public MyClass(int value){
}
//And within a object, the methods look like this
public void myMethod(MyClass this){ //A reference of a object of MyClass
this.field = 10; // The current object field
}
}

Categories

Resources