Java: Class.this - java

I have a Java program that looks like this.
public class LocalScreen {
public void onMake() {
aFuncCall(LocalScreen.this, oneString, twoString);
}
}
What does LocalScreen.this means in aFuncCall?

LocalScreen.this refers to this of the enclosing class.
This example should explain it:
public class LocalScreen {
public void method() {
new Runnable() {
public void run() {
// Prints "An anonymous Runnable"
System.out.println(this.toString());
// Prints "A LocalScreen object"
System.out.println(LocalScreen.this.toString());
// Won't compile! 'this' is a Runnable!
onMake(this);
// Compiles! Refers to enclosing object
onMake(LocalScreen.this);
}
public String toString() {
return "An anonymous Runnable!";
}
}.run();
}
public String toString() { return "A LocalScreen object"; }
public void onMake(LocalScreen ls) { /* ... */ }
public static void main(String[] args) {
new LocalScreen().method();
}
}
Output:
An anonymous Runnable!
A LocalScreen object
This post has been rewritten as an article here.

It means the this instance of the outer LocalScreen class.
Writing this without a qualifier will return the instance of the inner class that the call is inside of.

The compiler takes the code and does something like this with it:
public class LocalScreen
{
public void method()
{
new LocalScreen$1(this).run;
}
public String toString()
{
return "A LocalScreen object";
}
public void onMake(LocalScreen ls) { /* ... */ }
public static void main(String[] args)
{
new LocalScreen().method();
}
}
class LocalScreen$1
extends Runnable
{
final LocalScreen $this;
LocalScreen$1(LocalScreen $this)
{
this.$this = $this;
}
public void run()
{
// Prints "An anonymous Runnable"
System.out.println(this.toString());
// Prints "A LocalScreen object"
System.out.println($this.toString());
// Won't compile! 'this' is a Runnable!
//onMake(this);
// Compiles! Refers to enclosing object
$this.onMake($this);
}
public String toString()
{
return "An anonymous Runnable!";
}
}
As you can see, when the compiler takes an inner class it converts it to an outer class (this was a design decision made a LONG time ago so that VMs did not need to be changed to understand inner classes).
When a non-static inner class is made it needs a reference to the parent so that it can call methods/access variables of the outer class.
The this inside of what was the inner class is not the proper type, you need to gain access to the outer class to get the right type for calling the onMake method.

Class.this allows access to instance of the outer class. See the following example.
public class A
{
final String name;
final B b;
A(String name) {
this.name = name;
this.b = new B(name + "-b");
}
class B
{
final String name;
final C c;
B(String name) {
this.name = name;
this.c = new C(name + "-c");
}
class C
{
final String name;
final D d;
C(String name) {
this.name = name;
this.d = new D(name + "-d");
}
class D
{
final String name;
D(String name) {
this.name = name;
}
void printMe()
{
System.out.println("D: " + D.this.name); // `this` of class D
System.out.println("C: " + C.this.name); // `this` of class C
System.out.println("B: " + B.this.name); // `this` of class B
System.out.println("A: " + A.this.name); // `this` of class A
}
}
}
}
static public void main(String ... args)
{
final A a = new A("a");
a.b.c.d.printMe();
}
}
Then you will get.
D: a-b-c-d
C: a-b-c
B: a-b
A: a

I know what is your confusion.I am encounter the problem just now, it should have special scene to distinguish them.
class THIS {
def andthen = {
new THIS {
println(THIS.this.## + ":inner-THIS.this.##")
println(this.## + ":inner-this.##")
new THIS {
println(THIS.this.## + ":inner-inner-THIS.this.##")
println(this.## + ":inner-this.##")
}
}
}
def getInfo = {
println(THIS.this.## + ":THIS.this.##")
println(this.## + ":this.##")
}
}
You can see the diff between THIS.this and this in new THIS operation by hashcode( .## )
test in scala console :
scala> val x = new THIS
x: THIS = THIS#5ab9b447
scala> val y = x.andthen
1522119751:inner-THIS.this.##
404586280:inner-this.##
1522119751:inner-inner-THIS.this.##
2027227708:inner-this.##
y: THIS = THIS$$anon$1#181d7f28
scala> x.getInfo
1522119751:THIS.this.##
1522119751:this.##
THIS.this always point to outer THIS class which is refer by val x,but this is beyond to anonymous new operation.

Related

Pass object of any type to class B

I want to be able to pass Object from any class to a specific class. How do i do this? I pass the object in the constructor of the receiving class. One workaround i know is using static variables, but i need the whole object not just the variables.
public class tryitout
{
public static void main(String[] args) {
A a = new A();
B b = new B(a);
b.print();
}
}
class A implements Serializable
{
public int a;
public String b;
A()
{
this.a = 12;
this.b =" nach";
}
}
class B
{
Object obj;
B(Object o)
{
obj = o;
}
void print()
{
System.out.println(obj.a + " "+ obj.b);
}
}
Using Generics :
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class tryitout {
public static void main(String[] args) {
ClassA a = new ClassA("sap",11);
ClassB<ClassA> b = new ClassB<ClassA>(a);
b.print();
}
}
public class ClassA {
private String name;
private int id;
public ClassA(String name, int id) {
super();
this.name = name;
this.id = id;
}
#Override
public String toString() {
return "ClassA [name=" + name + ", id=" + id + "]";
}
}
public class ClassB<T> {
private T genericObj;
public ClassB(T genericObj){
this.genericObj = genericObj;
}
public void print() {
Field nameField = getField("name");
Field idField = getField("id");
try {
System.out.println(nameField.get(genericObj));
System.out.println(idField.getInt(genericObj));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
private Field getField(String FieldName) {
Field fld = null;
try {
fld = genericObj.getClass().getDeclaredField(FieldName);
if(Modifier.isPrivate(fld.getModifiers())) {
fld.setAccessible(true);//To get access over private fields
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
return fld;
}
}
using generics you can access method also.
I don't know your exact purpose,otherwise other classes can extend any particular Abstract class and you can use that Abstract class as a type inside classB.
public class TypeClass {
protected String name;
protected int id;
protected void paint(){
System.out.println("name: " + name + " | id: " + id);
}
}
public class ClassC extends TypeClass{
public ClassC(String name, int id) {
super();
this.name = name;
this.id = id;
}
#Override
public String toString() {
return "ClassA [name=" + name + ", id=" + id + "]";
}
}
package javaConcept.generics;
public class ClassD {
private TypeClass typeClass;
public ClassD(TypeClass typeClass) {
this.typeClass = typeClass;
}
public void newPaint() {
typeClass.paint();
}
}
public class TempoClass {
public static void main(String[] args) {
ClassC c = new ClassC("sap",11);
ClassD b = new ClassD(c);
b.newPaint();
}
}
maybe use static blocks and anonymous blocks some thing like this
public class HelloWorld{
public static void main(String []args){
B ob1= new B();
C ob2= new C(B.ob);
D ob3= new D();
C ob4= new C(ob3.ob);
}
}
class A
{
//this is empty class just for sake of object to be created
public void imWorking()
{
System.out.println("test");
}
}
class B
{
public static A ob;
static{ob=new A();}//static called once class gets loaded
}
class C
{
public C(){}//Default constructor
public C(A a){a.imWorking();}
}
class D
{
public A ob;
{ob=new A();}//ananomous block calls everytime a new object is created
}
more info Static Initialization Blocks blocks & anonymous blocks][1]

How do I access fields from a type parameter in Java?

I have two classes X e Y with the same static members:
class B {
public static final String Base = "Base";
}
class X extends B {
public static final String First = "First A";
public static final String Second = "Second A";
}
class Y extends B {
public static final String First = "First B";
public static final String Second = "Second B";
}
In another class, I need a function that will use one class or the other:
class C {
public <Data> void f() {
System.out.println("Operation " + Data.Base);
System.out.println("Running " + Data.First);
System.out.println("Running " + Data.Second);
}
}
The idea is to use C as follows:
C c = new C();
if (whatever()) {
c.f<X>();
} else {
c.f<Y>();
}
But the code above is not valid, is there a way to achieve the desired behaviour in Java?
You'll need to declare non-static methods
abstract class B {
public static final String Base = "Base";
public abstract String getFirst();
public abstract String getSecond();
}
class X extends B {
public static final String First = "First A";
public static final String Second = "Second A";
public String getFirst() { return First; }
public String getSecond() { return Second; }
}
class Y extends B {
public static final String First = "First B";
public static final String Second = "Second B";
public String getFirst() { return First; }
public String getSecond() { return Second; }
}
class C {
public void f(B b) {
System.out.println("Operation " + B.Base);
System.out.println("Running " + b.getFirst());
System.out.println("Running " + b.getSecond());
}
}
You are most likely came from C++ where templates can have implicit interfaces and checked by the compiler (probably bad wording, I'm not a C++ guy).
In Java, generic type parameters cannot be used in a static context, so static method calls of a Generic Type parameters are not possible with Java Generics.
Here is some reference from JLS:
It is a compile-time error to refer to a type parameter of a generic
class C anywhere in:
the declaration of a static member of C (§8.3.1.1, §8.4.3.2, §8.5.1),
or
the declaration of a static member of any type declaration nested
within C, or
a static initializer of C (§8.7), or
a static initializer of any class declaration nested within C.
No, you can't do that. The generic type parameter Data doesn't have any boundary so it could be anything. Besides that you can't use the type parameter like Data.Base etc.
What you could do: pass a Class<Data> to the method and use reflection to get the fields. That's not beautiful though, so you might want to rethink your requirements/approach.
Example (warning: use with care!):
<Data> void f(Class<Data> param ){
printStaticFieldIfPresent( param, "Base" );
printStaticFieldIfPresent( param, "First" );
printStaticFieldIfPresent( param, "Second" );
}
void printStaticFieldIfPresent( Class<?> c, String fieldName ) {
try {
System.out.println(c.getField(fieldName).get(null));
} catch( NoSuchFieldException e) {
//ignore or log
}
}
Your use case would then look like this:
C c = new C();
if (whatever()) {
c.f(X.class);
} else {
c.f(Y.class);
}
But yet again: you should revisit your design approach first. Java works differently from C++ and classes themselves are often no good option for "singletons" - you're almost always better of creating instances even if only one.
package exchange;
import org.apache.poi.ss.formula.functions.T;
import java.lang.reflect.Field;
/**
* Created by huqingxin on 2018/1/24.
*/
public class TextModel {
static class B {
public static final String Base = "Base";
}
static class X extends B {
public static final String First = "First A";
public static final String Second = "Second A";
}
static class Y extends B {
public static final String First = "First B";
public static final String Second = "Second B";
}
static class C {
public void f(Class<? extends B> t) throws IllegalAccessException {
Field[] declaredFields = t.getDeclaredFields();
for (Field declaredField : declaredFields) {
String name = declaredField.getName();
String o = (String)declaredField.get(name);
System.out.println(o);
}
}
}
public static void main(String[] args) throws IllegalAccessException {
C c = new C();
if (false) {
c.f(X.class);
} else {
c.f(Y.class);
}
}
}
sorry,maybe like this?

Calling a super toString() method but using current class' variables

say we have 2 classes:
public class A {
private String name = "A";
public String toString()
{
return (name + "some random text");
}
}
public class B extends A{
private String name = "B";
public String toString()
{
return (super.toString());
}
}
When I tried to print the B.toString() in my driver class, it will still print the name from class A instead of the name from class B. How can I change it so it will use the variable name from class B instead?
You can do it through the use of constructors -
public class HelloWorld {
public static void main(String[] args) {
A a = new A("A String");
B b = new B("B String");
System.out.println(a.toString()); // A String some random text
System.out.println(b.toString()); // B String some random text
}
}
class A {
protected String name;
A(String name) {
this.name = name;
}
public String toString() {
return name + " some random text";
}
}
class B extends A {
B(String name) {
super(name);
}
#Override
public String toString() {
return (super.toString());
}
}
Because B inherits from A, the name field is setup correctly when you pass a string to the constructor for B.

Java Passing variables around classes

I am new to java and am trying to pass variables like in the following example from one class to another, im wondering is this possible and how i would go about it if it is.
As this code does not work as it is not static.
Main Class
public class testAll
{
public static void main(String[] args)
{
One one = new One();
Two two = new Two();
}
}
The first class:
public class One
{
public int test = 4;
public int getTest()
{
return this.test;
}
}
The second class:
public class Two
{
public void value()
{
System.out.print("Var is: " + One.getTest());
}
}
Thanks,
Naz
Lets consider this, if you want to access a variable in Class A from Class B then Class A needs to know about Class B.
public class A {
public A(B classB){
this.classB = classB;
}
public void printValue(){
System.out.println(this.classB.getTest());
}
}
Now you will need to pass an instance of ClassB to ClassA in the constructor so that Class A has a reference to ClassB when it calls printValue();
ClassB b = new ClassB();
ClassA a = new ClassA(b);
b.getTest();
a.printValue();
You have to create an instance for class One first. Try this
public void value()
{
One one_object = new One();
System.out.print("Var is: " + one_object.getTest());
}
public class Two {
private One one;
public Two(One one) {
this.one = one;
}
public void printValue() {
System.out.print("Var is: " + one.getTest());
}
}
public class Main {
public static void main(String [] args) {
One one = new One();
Two two = new Two(one);
two.printValue();
}
}
There are two way - pass a reference or pass a value:
public class One {
private int value = 0;
public One(final int value) {
this.value = value;
}
public int getValue() { return value; }
}
public class Two {
private One one = null;
public Two(final int value) {
this.one = new One(value);
}
public Two(final One one) {
this.one = one;
}
public int getValue() { return one.getValue(); }
}
When passing a reference to a One instance, the value is read from One and will only change it the value held inside the One instance changes. When passing a primitive (int, boolean ...) the value is copied and "owned" by the Two instance. Read some more about the differences of references and values to grasp the idea. It's quite simple, once you get the idea.

Inheritance in Java

Consider the following code in Python:
class A(object):
CLASS_ATTRIBUTE = 42
def f(self):
return "CLASS_ATTRIBUTE: %d" % self.CLASS_ATTRIBUTE
class B(A):
CLASS_ATTRIBUTE = 44
Now A().f() and B().f() return "CLASS_ATTRIBUTE: 42" and "CLASS_ATTRIBUTE: 44" respectively.
How can I achieve a similar effect in Java? I want a CLASS_ATTRIBUTE field to be initialized statically and redefined in the inherited class but the f method should be only defined in the base class.
Is there a particular reason you want the attribute to be static? In Java the typical way you'd do this is to have A contain a protected variable that you then set in the constructors of the 2 classes:
public class A
{
protected int CLASS_ATTRIBUTE;
public A()
{
CLASS_ATTRIBUTE = 42;
}
public String f()
{
return "CLASS_ATTRIBUTE: " + CLASS_ATTRIBUTE;
}
}
public class B extends A
{
public B()
{
CLASS_ATTRIBUTE = 44;
}
}
Alternatively (and probably more consistent with Java design patterns) you'd declare a function that you can override to return the value instead of using a member variable.
Short answer: you cant solve it like this in Java. You'll have to solve it in another way.
In Java you can't override or "redeclare" fields in subclasses, and you can't override static methods.
It can be solved using an ugly reflection-hack (should be avoided though):
public class Main {
public static void main(String... args) {
A a = new A();
B b = new B();
System.out.println(a.f()); // Prints 42.
System.out.println(a.fReflection()); // Prints 42.
System.out.println(b.f()); // Prints 42.
System.out.println(b.fReflection()); // Prints 44.
}
}
class A {
static int CLASS_ATTRIBUTE = 42;
public int f() {
return CLASS_ATTRIBUTE;
}
public int fReflection() {
try {
return getClass().getDeclaredField("CLASS_ATTRIBUTE").getInt(null);
} catch (Exception wontHappen) {
return -1;
}
}
}
class B extends A {
// Compiles, but will not "override" A.CLASS_ATTRIBUTE.
static int CLASS_ATTRIBUTE = 44;
}
You can't do this directly with only a variable, because in Java variables cannot override (they only shadow the super classes variables).
You need to use a protected "getter" method, which can then be overridden by the subclass:
class A
{
private int attribute=42;
...
protected int getAttribute() {
return attribute;
}
}
class B
extends A
{
private int attribute=44;
...
protected int getAttribute() {
return attribute;
}
}
But note there's a special consideration to calling methods from an object's constructor, in that it allows object code to run before object construction is complete.
I'm not sure if you meant "statically" literally or not, but here's a brief example of how inheritance at it's most basic form looks in Java. Note that using a getter method to access the variable is a better idea for several reasons -- this is just an example.
public class Dog {
protected String whatISay = "Woof!";
public void speak(){
System.out.println(whatISay);
}
}
public class Poodle extends Dog {
public Poodle(){
whatISay = "Yap!";
}
}
public class Main {
public static void main(String[] args){
Poodle fluffy = new Poodle();
fluffy.speak();
Dog dog = new Dog();
dog.speak();
}
}
Yap!
Woof!
This way of doing it introduces as little intrusion as I could think of. setAttribute() could be named something like setDefaultValue() if that's clearer.
public class A
{
protected int attribute;
public A()
{
setAttribute();
}
public String f()
{
return "CLASS_ATTRIBUTE: " + attribute;
}
protected void setAttribute()
{
attribute = 42;
}
}
public class B extends A
{
#Override
protected void setAttribute()
{
attribute = 44;
}
}
public class Main
{
public static void main(String[] args)
{
A a = new A();
B b = new B();
System.out.println("A: " + a.f());
System.out.println("B: " + b.f());
}
}

Categories

Resources