Reputation: 10831
I might just be unable to google for the right words, but I can't find an answer to the following question.
Is it possible to explicitly set the superclass of a new class instance. E.g. I have a SuperClazz
instance and want to create a new instance of Clazz
which extends SuperClazz
. Can I just do something like this (the code is just what I want to do, it doesn't compile and is not correct):
class Clazz extends SuperClazz{
Clazz(SuperClazz superInstance){
this.super = superInstance;
}
}
Upvotes: 3
Views: 5303
Reputation: 26
i cant claim that this will always work, you should always use copy-constructor as far as you can but in some cases (like you dont have access/right to change code or dont want to produce complexities) you can use this (example:),
import java.lang.reflect.Field;
import java.net.Socket;
public class SmarterSocket extends Socket {
public SmarterSocket(Socket s) {
super(); // default constructor for super instance
// will iterate over public/private fields of "s" (superclass not included)
for(Field f : s.getClass().getDeclaredFields()){
try {
f.setAccessible(true);
f.set(this,f.get(s));
}catch (Exception ignored){}
}
}
public void doSmartStuff(){
System.out.println("smarter");
}
}
...
public static void main(String[] args){
try {
Socket s = new Socket();
s.connect(new InetSocketAddress("stackoverflow.com",80));
SmarterSocket ss = new SmarterSocket(s);
ss.close();
System.out.println("is SmartSocket closed: " + ss.isClosed());
System.out.println("is Socket closed: " + s.isClosed());
s.getOutputStream().write("hellow".getBytes()); // write to s
} catch (IOException e) {
e.printStackTrace();
}
}
is SmartSocket closed: true
is Socket closed: false
java.io.IOException: Socket Closed
at java.base/java.net.AbstractPlainSocketImpl.getOutputStream(AbstractPlainSocketImpl.java:489)
at java.base/java.net.Socket$3.run(Socket.java:972)
at java.base/java.net.Socket$3.run(Socket.java:970)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.net.Socket.getOutputStream(Socket.java:969)
at Main.main(Main.java:47)
i used above example for hooking some monitors inside socket
but you have to be cautious:
1- reflection is complex: sometimes fields are being used for synchronization or more sophisticated stuff, you probably shouldn't update static (or more clearly static final) fields, you should have proper knowledge about internals of the class you are proxying it,and do some heavy tests to make sure everything is going smoothly
2- reflection is slow in runtime: test it, if it suit you let it be there
Upvotes: 0
Reputation: 115328
I think you have some missunderstanding in meaning or terms you are using.
Instance (or object) is what you create using new Clazz()
at runtime. You cannot change it (unless you are using byte code modification tricks).
What yo really want is to create 2 classes: base class and its subclass. Here is the simplest example.
class SuperClazz {
}
class Clazz extends SuperClazz {
}
If you want to call exlplitly constructor of super class from constructor of subclass use super()
:
class Clazz extends SuperClazz {
public Clazz() {
super();
}
}
Upvotes: 1
Reputation: 691695
You're mixing inheritance and delegation. When an object calls
super.doThis();
it doesn't call doThis
on another object which has the type of the object's superclass. It calls it on himself. this
and super
are the same thing. super
just allows to access the version of a method defined in the superclass, and overridden in the subclass. So, changing the super instance doesn't make sense: there is no super instance.
Upvotes: 7
Reputation: 10762
The super class is always instantiated implicitly, so you cannot do it — "plant" the super class inside an extending class. What you probably want is a copy constructor.
Upvotes: 4