Java中有类似分支/跳转表的东西吗?
Java有类似分支表或跳转表的东西吗?
分支表或跳转表是根据维基百科,
用于描述使用分支指令表将程序控制(分支)转移到程序的另一部分(或可能已动态加载的不同程序)的有效方法的术语。
Java 是否有类似的东西,或者我只需要使用 if/else if/else 或 case 语句?
Does Java have something similar to a branch or jump table?
A branch or jump table table is, according to wikipedia,
a term used to describe an efficient method of transferring program control (branching) to another part of a program (or a different program that may have been dynamically loaded) using a table of branch instructions.
Does Java have something like this or do I just have to use if/else if/else or case statements?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
Java有一个switch语句,但是它是否编译为字节码中的跳转表与实现相关。 一般来说,如果编译器在 switch 语句中为每种情况找到了很好的常量,它们就会为您构建一个跳转表。 不过,我不确定您是否应该真正关心它是如何实现的。 如果您首先使用 Java 进行编码,那么您可能可以让编译器和 JIT 为您处理这些事情。
请注意,switch 仅适用于整数基元类型和枚举,因此如果您使用其他对象类型,您确实需要使用 if/else 语句(并且您可能不应该比较双精度数或浮点数无论如何都是平等的)。
最后,即使枚举引用在技术上是“恒定的”,一些编译器只会在您打开枚举时生成跳转表如果您的 switch 语句位于定义枚举的同一编译单元中。 否则,它将为您生成一个 if/else 链(就像您必须为常规对象所做的那样)。 有关详细信息,请参阅有关扩展对象开关使用的 java.net 论坛< /a>.
Java has a switch statement, but whether it compiles to a jump table in bytecode is implementation-dependent. In general, compilers will build you a jump table if they find nice constants for each case in your switch statement. I'm not sure you should really care how it's implemented, though. If you're coding in Java in the first place, you're probably just fine letting the compiler and the JIT take care of these things for you.
Note that switch only works with integer primitive types and enums, so you do need to use if/else statements if you're using other object types (and you probably shouldn't be comparing doubles or floats for equality anyway).
Finally, even though enum references are technically "constant", some compilers will only generate you a jump table when you switch on enums if your switch statement is in the same compilation unit where the enum is defined. Otherwise, it will generate you an if/else chain (as you'd have to do for regular objects). For the nitty gritty details, see the java.net forums on extending switch usage for Objects.
我认为 case 语句(使用 java 中的 switch )是等效的。
此外,在面向对象编程中,开关可以编码一次,然后让多态性来完成工作。
来自:http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.html
这取决于您的要求。
I think case statements ( with the switch in java ) is the equivalent.
Additionally in OOP the switch could be coded once and then let polymorphism to the job.
From : http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.html
It depends on your requirements.
转移程序控制的一种方法是调用当有多个函数可供选择时,调用正确函数的一种方法是将其与对象的类型联系起来,这就是所谓的多态性,Java 和其他面向对象语言都具有通过继承(子类化)实现的多态性。不确定它是如何在 Java 中实现的,但在 C++ 中,每个对象中(通常?或总是?)都有一个指向其类的 v 表的指针,其中包含指向虚拟函数的指针,
我严重怀疑是否缺少用户。 - 定义的跳转表会削弱java应用程序的性能。
One way to transfer program control is to call a function. One way to call the right function when you have several to choose from, is to key it off of the type of an object. That's called polymorphism. Java and other Object Oriented languages have polymorphism, implemented through inheritance (subclassing). Not sure how it's implemented in Java, but in C++ there's (generally? or always?) a pointer in each object that points to the v-table for it's class, which contains pointers to virtual functions.
I seriously doubt the lack of a user-defined jump table is going to cripple the performance of your java application.
是的,一点没错。
如果您编写了一个 switch 语句,那么根据不同的情况,该 switch 会被转换为字节码中的 tableswitch 指令。 一般来说
实现这一点的最简单方法是使用 java 枚举,它由编译器专门处理。 相关文档位于 Java 虚拟机规范。 当然,JIT 编译器几乎肯定会直接将这些直接转换为您运行的任何平台的机器代码中的非常快速的开关。
话虽如此,您的问题的真正答案是“这是您在编写机器代码而不是使用高级语言编程时担心的事情”。
Yes, absolutely.
If you code a switch statement, then depending on various things the switch is converted into a tableswitch instruction in bytecode. Generally
The simplest way to acheive this is to use java enums, which are handled specially by the compiler. The relevant documentation is in the Java Virtual Machine Specification. Of course, the JIT compiler almost certainly converts these directly into very fast switches in the machine code of whatever platform you are running on.
Having said that, the real answer to your question is "this is the sort of thing that you worry about when you are doing machine code, not programming in a high-level language".
我不认为您需要 Java 中的此类性能技巧。 我会首先集中精力编写可读的代码并使用合适的算法 - 这些将提供比您正在讨论的更多的性能优势。
在大多数独立应用程序中,绝大多数时间都花在等待用户执行某些操作。 在大多数 Web 应用程序中,在 JVM 中运行字节码的时间应该被网络时间、数据库时间或业务逻辑所淹没。
如果您确实担心 Java 应用程序的部分性能,您可以将其移至 JNI 代码中并完全绕过 Java 解释器。
I don't believe that you need those sort of performance hacks in Java. I would concentrate first of writing readable code and using decent algorithms - these will deliver more performance benefits than what you're discussing.
In most standalone applications, the vast majority of time is spent sitting around waiting for the user to do something. In most web applications, the amount of time running bytecode in the JVM should be swamped by network time, database time or business logic.
If you're really worried about the performance of part of your Java app, you can move it into JNI code and bypass the Java interpreter altogether.
我认为这就是一些 switch 语句“在幕后”实现的方式。
除此之外,您还可以使用
HashMap
执行类似的操作,其中使用map.get(something).invoke()
。 但这有点违背了目的,因为它不会像跳转表那么快,而且我想不出 OOP 编程/多态性不能更好、更干净地完成工作的好例子。I think that is how some switch statements are implemented "under the hood" so to speak.
Other than that, you could do something similar with something like
HashMap<whatever, Method>
, where you usemap.get(something).invoke()
. But that kinda defeats the purpose because it wouldn't be as fast as a jump table, and I can't think of a good case where OOP programming/polymorphism wouldn't do the job better and cleaner.你所说的这种分支/跳转表并不是由Java、C等高级语言直接提供的,而是由编译器以机器码或字节码生成的。 换句话说,您的编译器可能会使用它们,但您看不到它们。
THe kind of branch/jump tables you're talking about are not directly provided by high level languages such as Java, C, etc., but are generated by compilers in machine code or byte code. In other words, your compiler may use them but you don't see them.
您可以使用枚举来执行此操作。
You can use enum to do this.
您可以使用反射和存储匿名内部类的通用 HashMap 来做到这一点,但这将是一个可怕的黑客行为。
由于本机匿名方法,在 C# 中执行起来非常优雅,但在 Java 中则不然。
You could do this with reflection and a generic HashMap that stored anonymous inner classes but it would be a horrible hack.
It is really elegant to do in C# due to native anonymous methods, but not in java.