在Java中,转换需要多少处理和内存使用?

在Java中,转换需要多少处理和内存使用?,java,optimization,casting,memory-management,Java,Optimization,Casting,Memory Management,我正在考虑是否最好有两个指针,一个用于每个对象子类和super,或者是否应该使用casting 这将使用多少系统资源: objectName.functionOne(); ((SubClass) objectName).functionOther(); 它是否比: SuperClass objectA = (SuperClass) getSameInstance(); SubClass objectB = getSameInstance(); objectA.functionOne(); ob

我正在考虑是否最好有两个指针,一个用于每个对象子类和super,或者是否应该使用casting

这将使用多少系统资源:

objectName.functionOne();
((SubClass) objectName).functionOther();
它是否比:

SuperClass objectA = (SuperClass) getSameInstance();
SubClass objectB = getSameInstance();
objectA.functionOne();
objectB.functionOther();
基本上,我的主要问题是关于铸造所使用的资源,而不是制作一个额外的指针。看起来我可以保存多个在线模式转换,例如:

((SubClass) objectName).functionOther();
然而,这值得吗

谢谢,
格拉

更新: 我的问题有一些不清楚的地方。基本上,我有一个超类,我在一个大函数中使用它。它与三个子类一起工作。超级班的一些人正在按我的意愿工作。然而,我在一些地方遇到了障碍,我必须使用来自三个不同子类之一的函数;仅在其中一个子类中的函数

我可以:

SuperClass instanceRef;
SubClass instanceRef2;

instanceRef.etc()
instanceRef.etc2()
instanceRef.etc3()
instanceRef2.specialSubClassOnlyCall();
instanceRef2.specialSubClassOnlyCall2();
或者我可以:

SuperClass instanceRef;

instanceRef.etc()
instanceRef.etc2()
instanceRef.etc3()
((SpecialSubClass)instanceRef).specialSubClassOnlyCall();
((SpecialSubClass)instanceRef).specialSubClassOnlyCall2();
然而,我不知道哪一个更有效

更新2: 下面是一个示例,向您展示我所说的内容:

class Shape
Triangle extends Shape
Square extends Shape
Circle extends Shape
Cube extends Shape
双指针示例:(下方向是一个额外的指针。)

或者我可以这样做。(下面是一组演员阵容。)

那么,五次抛投比一次多投更糟糕吗?是六次还是二十次?一次投法比指针差


Grae

做任何能让代码更清晰的事情,忘记微观优化。

只需选择更易于阅读和维护的解决方案(可能是第一个解决方案)。在如此低的优化水平下,除了在边缘情况下需要额外提高0.01%的性能外,这真的不值得

值得一提的是,您实际上不需要将子类强制转换为超类引用(列出了第二种解决方案),而只需要反过来。将超类强制转换为子类时,通常首选在强制转换之前使用
instanceof
验证其类型,而不是进行假设。

强制转换不是在运行时完成的“操作”。编译器只需要它来确保静态类型安全

只要看一看JVM代码,这两种方法基本上是等价的,它们实现为

CHECKCAST Main$B
INVOKEVIRTUAL Main$B.mySubMethod()V
因此存在一个小的开销,但在这两种情况下都是一样的(因为您无论如何都要进行向下广播)。

从您的代码片段来看,
getSameInstance()
返回一个
子类。在这种情况下,最简单的解决方案是

SubClass objectB = getSameInstance();
objectB.functionOne();
objectB.functionOther();
没有演员,没有烦恼:-)

正如其他人正确指出的那样,主要关注的应该是代码的可读性和简单性,而不是性能仅当您知道需要优化时才进行优化,并且(使用探查器)已证明瓶颈在代码中的位置。即使在这种情况下,微优化在Java中也很少有用

另一个注意事项:如果方法很重(在这种情况下,您实际上使代码变慢,而不是变快),或者有副作用(在这种情况下,程序的行为可能会明显改变),那么调用同一方法两次可能会有问题

顺便说一句,在代码段的这一行

SuperClass objectA = (SuperClass) getSameInstance();
绝对不需要将返回值向上转换到超类
——超类引用始终可以指向子类对象。(我猜编译器无论如何都会忽略这种向上转换,因此字节码中不会有任何差别。)

更新 你还没有发布我要求的方法声明。但根据你的解释,我想应该是这样的

public Shape getSomeRandomShape();
这是正确的吗?

顺便说一句,这意味着您的第二个原始代码段(使用
getSameInstance()
调用)不正确-强制转换应该是相反的方式。你设法把我弄糊涂了,所以你得到了一个令人困惑的答案:-)

同样在最新的示例中,您不需要将返回值强制转换为
(Shape)
,因为它已经是
Shape
。演员阵容只是把你的代码弄得乱七八糟。类似地,更新2的第二个示例中的许多强制转换使得代码难以阅读。我更喜欢第一个版本,有两个引用(不是指针,顺便说一句,Java没有指针)


这里我只关心代码的可读性—正如其他人已经指出的,您真的不应该浪费时间考虑强制转换的成本。只需将注意力集中在使代码尽可能简单易读上。您很可能永远不会注意到上面显示的两个代码段的性能之间的细微差别(除非它们在紧循环中执行了数百万次——但是,我想,JIT无论如何都会优化丢弃)。但是,您会注意到理解一个代码段与理解另一个代码段所需的时间不同,对于熟悉此代码的人-或者已经忘记了详细信息的人,这可能是您在大约6个月后的情况。

在类似情况下,可读性和代码维护应该是您的优先事项,而不是性能,除非你真的遇到了瓶颈(极不可能)


但是,没有理由有两个引用(指针)。只需引用子类。在几乎所有情况下(重载方法的参数是我所知的唯一例外),可以使用超类引用执行的任何操作都可以使用子类引用执行。

假设您有一台64位机器,它可以节省8字节的资源。假设你花了10分钟来考虑它。这是不是很好地利用了你的时间

1GB使服务器成本增加约100美元,因此8个字节的成本约为0.0000008美元

你10分钟的时间相当于1美元的最低工资


资源是可重用的,你的时间不是。更重要的是,任何人阅读/支持您的代码的时间可能会更加昂贵,这就是为什么简单性/清晰性要重要得多。

维护两个都不是一个好的做法,可以吗
SuperClass objectA = (SuperClass) getSameInstance();
public Shape getSomeRandomShape();