考虑A类
class A {
int i;
int j;
int k;
}
这是B级
class B {
int a;
int b;
int c;
}
我想知道java是否有任何这样的ting允许编写/定义我们自己的自定义构建逻辑。
例如 将B类的对象转换为A类的对象
i - > a //我指向
的值j - > b // j指向b的值
k - > c // k指向c
的值
(我可以根据自己的意愿自定义逻辑)
我有一些重量级的对象要“投射”到其他一些类中使用,我不想为此编写转换器方法。
(转换只对所考虑的对象进行操作,不会创建另一个对象)
对此有何想法/建议?
感谢预期!
答案 0 :(得分:1)
您可以使用ModelMapper
(documentation)之类的框架来定义maping逻辑,并使用它将对象从一种类型转换为另一种类型的对象。例如。这就是配置的方式:
//Model Classes
class A{
int a;
}
class B{
int d;
}
//Mappings
PropertyMap<A, B> map = new PropertyMap<A, B>() {
protected void configure() {
map(source.a, destination.d);
}
};
//Test Program
public static void main(String[] args) throws Exception {
ModelMapper mapper = new ModelMapper();
PropertyMap<A, B> map = new PropertyMap<A, B>() {
protected void configure() {
map(source.a, destination.d);
}
};
mapper.addMappings(map);
A a = new A();
a.a = 10;
B b = mapper.map(a, B.class);
System.out.println(b.d);
}
答案 1 :(得分:0)
这有助于破坏Java的安全目的,原因有两个。
让我们考虑一下类代码的更新版本。
class A {
int i;
int j;
int k;
int l;
}
class B {
int a;
int b;
int c;
}
现在想象如果你做了类似这样的事情会发生什么,假设上面写的类:(警告:代码不会编译)
public static void main(String[] args)
{
B classTwo = new B();
A classOne = (A) classTwo;
classOne.l = 3; // <-- what would happen?
}
如您所见,它不起作用,因为创建B的实例不会正确分配变量。这就是为什么Java 不允许允许这样投射的原因。
Java允许的是在超类和子类之间进行转换。
例如:
class Fruit {
int i;
}
class Apple extends Fruit {
int j;
}
现在在main
函数中:
水果f =新水果();
Apple a =(Apple)f; //这会编译,但会引发ClassCastException
你会问,为什么会引发ClassCastException? Apple扩展了Fruit。
是的,Apple扩展了Fruit。但是,Fruit不为j
变量分配内存。
允许的另一种方法是将苹果变成水果,因为所有苹果都具有水果的特性(即使在现实生活中)。
如果你想使用你的铸造想法,你可以尝试一个界面。
interface C {
public int getVarOne();
public int getVarTwo();
// NO variables here, only functions
}
implements
(不是extends
)和interface
的任何类都必须实现其中定义的所有方法。
一旦实现了接口,行为类似于转换为超类。接口还有其他用途,但这超出了本问题的范围。
答案 2 :(得分:0)
没有。没有C语言中已知的联合。您无法直接在JVM中修改内存。这就是Java的重点。它牺牲了一些技巧的潜力,但最终代码往往比用C语言编写的代码更少,更容易维护。
如果您担心的是复制导致的内存消耗,您可以将A
和B
转换为接口。接口应该公开getter和setter。例如:int getI()
和int getA()
。然后你可以介绍一个实现它们的类。
接口调用引起的间接性会有一些性能成本,但在很多情况下,它不会是显而易见的。