Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在不创建新对象的情况下更改对象的类?_Java - Fatal编程技术网

Java 如何在不创建新对象的情况下更改对象的类?

Java 如何在不创建新对象的情况下更改对象的类?,java,Java,假设我有一个类Foo,两个类Foo1和Foo2扩展Foo 假设我有一个Foo f,结果是一个Foo1,我想在不使用构造函数的情况下更改它。如果只是更改f的字段,我可以手动执行: f.field1= .. f.field2= .. 但是如果我想把它变成Foo2,我该怎么办呢 重点是我想做这样的事情: Foo f=new Foo1( ...); Foo g=f; g=new Foo2(...); 当g改变时,f也会改变,但显然这不起作用。注意Java是and,所以除非Foo2是Foo的子类,否则

假设我有一个类Foo,两个类Foo1和Foo2扩展Foo

假设我有一个Foo f,结果是一个Foo1,我想在不使用构造函数的情况下更改它。如果只是更改f的字段,我可以手动执行:

f.field1= ..
f.field2= ..
但是如果我想把它变成Foo2,我该怎么办呢

重点是我想做这样的事情:

Foo f=new Foo1( ...);
Foo g=f;
g=new Foo2(...);

当g改变时,f也会改变,但显然这不起作用。

注意Java是and,所以除非
Foo2
Foo
的子类,否则它不会起作用。但即使这样做,您也只能更改变量的对象引用的类型(并启用多态性),而不能更改变量的类型。

在Java中不能这样做,因为您声明为的类型是您限制的类型。静态类型就是这样工作的。也就是说,您可以这样做:

Foo g = new Foo2();
((Foo2)g).gInstanceMethod();

其他人解释了为什么不能更改现有对象的类。但即使可以,由于Java引用的工作方式,您试图做的事情也不会起作用

 Foo f=new Foo1( ...);
此行在堆上分配一个新对象,调用
Foo1
构造函数对其进行初始化,并将对该对象的引用存储在变量
f

 Foo g=f;
此行将引用的值(即复制地址,而不是被引用的对象)复制到新变量
g

 g=new Foo2(...);

此行在堆上分配一个新对象,调用
Foo2
构造函数对其进行初始化,并将对新对象的引用存储到
g
中,覆盖先前存储在那里的引用。先前由
g
引用的对象永远不会受到此操作的影响。

您可能可以围绕这些行执行一些操作。注意:此代码是伪代码

abstract class Common{
...
}

class Foo{
  private Common currentReference;

  public Foo(...){
    currentReference = new Foo1();
  }

  public Foo changeReferenceToClass(Class clazz){
    ...
    currentReference = clazz.newInstance();
    ...
    return this;
  }

  public <T extends Common> T getReference()
  {
    return (T) currentReference;
  }
}

class Foo1 extends Common{
...
}

class Foo2 extends Common{
...
}

Foo f=new Foo( ... );
Foo g=f;
g=g.changeReferenceToClass(Foo2.class);
抽象类通用{
...
}
福班{
专用公共参考;
公共食品(…){
currentReference=new Foo1();
}
public Foo changeReferenceToClass(类clazz){
...
currentReference=clazz.newInstance();
...
归还这个;
}
公共T getReference()
{
返回(T)电流参考;
}
}
类Foo1扩展了公共{
...
}
类Foo2扩展了公共{
...
}
Foo f=新的Foo(…);
Foo g=f;
g=g.changeReferenceToClass(Foo2.class);
它的作用是:

  • 创建一个类,该类包含对具有
    common
    接口的对象的引用(在本例中为
    common
    抽象类)
  • 在构造默认值时实例化对该值的引用(
    Foo1
  • 提供
    更改
    获取
    参考的方法
  • 当您在一个位置将引用更改为Foo2时,您可以在所有位置访问它

在本例中,当您更改
g
以保留对
Foo2
的引用时,
f
也将保留对
Foo2
的引用。

您无法更改Java中的内容。您只能创建不同的内容。也许您想详细说明一下?如果您执行Foo1 f1=new Foo1();Foo g=f1;然后执行类似于g.setSomething的操作(“val”)-这改变了g和f1。我不知道为什么这里有g=new Foo2(),在这种情况下,“g改变时有f改变”是什么意思。我希望f和g变成Foo2,这是g.setSomething(“…”)无法实现的我怀疑这是因为Java是静态类型的。它可以是动态类型的,但您仍然无法更改对象的类。类型系统是在运行时工作的,编译器只是帮助遵循类型系统的规则。@EdwinDalorzo我忘了添加Java也是强类型的。