Java设置实例的超级实例

发布于 2024-12-23 03:11:15 字数 323 浏览 3 评论 0原文

我可能无法在谷歌上搜索正确的单词,但我找不到以下问题的答案。

是否可以显式设置新类实例的超类。例如,我有一个 SuperClazz 实例,并且想要创建一个扩展 SuperClazzClazz 的新实例。我可以做这样的事情吗(代码正是我想要做的,它不能编译并且不正确):

    class Clazz extends SuperClazz{

Clazz(SuperClazz superInstance){
    this.super = superInstance;
}
}

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;
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

迷途知返 2024-12-30 03:11:16

您正在混合继承和委托。当一个对象调用时,

super.doThis();

它不会在另一个具有该对象超类类型的对象上调用doThis。它要求他自己这样做。 thissuper 是同一件事。 super 只允许访问在超类中定义并在子类中重写的方法的版本。因此,更改超级实例没有意义:不存在超级实例。

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.

笔落惊风雨 2024-12-30 03:11:16

超类总是隐式实例化,所以你不能这样做——将超类“种植”在扩展类中。您可能想要的是一个复制构造函数。

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.

携君以终年 2024-12-30 03:11:16

我认为您对所使用的含义或术语存在一些误解。

实例(或对象)是您在运行时使用 new Clazz() 创建的内容。您无法更改它(除非您使用字节码修改技巧)。
你真正想要的是创建 2 个类:基类及其子类。这是最简单的例子。

class SuperClazz {
}

class Clazz extends SuperClazz {
}

如果你想从子类的构造函数中明确调用超类的构造函数,请使用super()
类 Clazz 扩展了 SuperClazz {
公共克拉兹(){
极好的();
}
}

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();
}
}

对你再特殊 2024-12-30 03:11:16

我不能声称这总是有效,你应该尽可能使用复制构造函数,但在某些情况下(比如你没有访问/有权更改代码或不想产生复杂性)你可以使用这个(例如: ),

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)

我使用上面的示例来挂钩套接字内的一些监视器

,但你必须小心:

1-反射很复杂:有时字段被用于同步或更复杂的东西,你可能不应该更新静态(或更清楚地静态最终) )领域,你应该有适当的知识你正在代理它的类的内部,并进行一些繁重的测试以确保一切顺利进行

2-反射在运行时很慢:测试它,如果它适合你就让它在那里

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文