如何在字节码级别实现Scala中的模式匹配?
它是否像一系列if (x instanceof Foo)结构或其他东西?它的性能影响是什么?
例如,给定以下代码(来自Scala By Example第46-48页),该方法的等效Java代码如何eval?
abstract class Expr
case class Number(n: Int) extends Expr
case class Sum(e1: Expr, e2: Expr) extends Expr
def eval(e: Expr): Int = e match {
case Number(x) => x
case Sum(l, r) => eval(l) + eval(r)
}
Run Code Online (Sandbox Code Playgroud)
PS我可以读取Java字节码,因此字节码表示对我来说已经足够了,但是对于其他读者来说,知道它看起来像Java代码会更好.
PPS Scala编程是否能够解答这一问题以及有关Scala如何实现的类似问题?我订购了这本书,但尚未到货.
等号:
object HelloWorld {
def main(args: Array[String]) = {
println("Hello!")
}
}
Run Code Online (Sandbox Code Playgroud)
没有等号:
object HelloWorld {
def main(args: Array[String]) {
println("Hello!")
}
}
Run Code Online (Sandbox Code Playgroud)
上述两个程序都以相同的方式执行.在博客文章中我不喜欢Scala中的内容我读到当缺少等号时,该方法将返回Unit(与Java相同void),因此返回值的方法必须使用等号.但是,不返回值的方法可以用任何一种方式编写.
在不返回值的Scala方法中使用等号的最佳实践是什么?
阅读Java 8从lambdas中产生的字节码类型,我想起了Java 5发布的时候.当时有Retroweaver和其他工具用于转换用JDK 5编译的字节码以在JRE 1.4上运行.
还有人为Java 8 lambdas创建了这样一个后向移植工具吗?它将让Java开发人员今天开始在生产质量的Java 7 JRE上使用lambdas,而不必等待6到12个月的Java 8 GA版本.
以下是我对后向传递器应该相对容易实现的原因的分析:
Java 8 lambdas似乎没有使用Java 7不具备的任何JVM功能(例如invokedynamic),并且java.lang.invoke.LambdaMetafactory该类及其依赖项看起来像纯Java,因此应该可以在第三方库中实现它们.因此,使用JDK 8编译的字节码可以通过添加带有LambdaMetafactory副本的第三方库(在不同的包下)并通过转换字节码来使用该元数据来在JRE 7上运行.也许还会生成一些合成类和方法来绕过可访问性检查,这java.lang.invoke.MagicLambdaImpl似乎意味着.或者为所有lambdas生成匿名内部类,就像一些支持lambda的早期访问JDK一样.
我现在正在调试一个程序,每个外部进程有两个线程,这两个线程继续使用while ((i = in.read(buf, 0, buf.length)) >= 0)循环读取Process.getErrorStream()和Process.getInputStream().
有时,当外部进程因JVM崩溃而崩溃时(请参阅这些hs_err_pid.log文件),那些读取该外部进程的stdout/stderr的线程开始消耗100%的CPU并且永远不会退出.循环体没有被执行(我在那里添加了一个日志语句),所以无限循环似乎在本机方法中java.io.FileInputStream.readBytes.
我在Windows 7 64位(jdk1.6.0_30 64位,jdk1.7.0_03 64位)和Linux 2.6.18(jdk1.6.0_21 32位)上重现了这一点.有问题的代码在这里,就像这样使用.请参阅这些链接以获取完整代码 - 以下是有趣的内容:
private final byte[] buf = new byte[256];
private final InputStream in;
...
int i;
while ((i = this.in.read(this.buf, 0, this.buf.length)) >= 0) {
...
}
Run Code Online (Sandbox Code Playgroud)
堆栈跟踪看起来像
"PIT Stream Monitor" daemon prio=6 tid=0x0000000008869800 nid=0x1f70 runnable [0x000000000d7ff000]
java.lang.Thread.State: RUNNABLE
at java.io.FileInputStream.readBytes(Native Method)
at java.io.FileInputStream.read(FileInputStream.java:220)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
- locked …Run Code Online (Sandbox Code Playgroud) 我写称为SBT插件SBT-JUMI它实现了SBT集成JUMI.现在sbt-jumi插件取决于当前的Jumi版本.
这是插件的build.sbt中的相关行:
libraryDependencies += "fi.jumi" % "jumi-launcher" % "0.5.376"
Run Code Online (Sandbox Code Playgroud)
插件的用户会将此添加到他的project/plugins.sbt文件中:
addSbtPlugin("fi.jumi.sbt" % "sbt-jumi" % "0.1.0")
Run Code Online (Sandbox Code Playgroud)
现在让我们说Jumi 0.6.400已经发布,它向后兼容.sbt-jumi插件的用户如何配置它使用Jumi 0.6.400,而不必发布新版本的插件?
以下是在Maven中如何做到这一点.但是如何在sbt中做到这一点?
我正在编写一个端到端测试,我的Java程序发布了它的所有资源 - 线程,服务器套接字,客户端套接字.它是一个库,因此通过退出JVM释放资源不是一种选择.测试线程的释放很容易,因为您可以向ThreadGroup询问其中的所有线程,但我还没有找到一种获取当前JVM正在使用的所有网络套接字列表的好方法.
有没有办法从JVM获取所有客户端和服务器套接字的列表,类似于netstat?我在Java 7上使用Netty和OIO(即java.net.ServerSocket和java.net.Socket).该解决方案需要在Windows和Linux上运行.
我的第一个偏好是使用纯Java从JVM中询问它.我试图寻找一个MX Bean或类似的,但没有找到任何.
另一个选择可能是连接到JVM的分析/调试API并询问Socket和ServerSocket的所有实例,但我不知道如何做到这一点以及是否可以在没有本机代码的情况下完成(AFAIK,JVMTI仅限本机) ).此外,它不应该使测试变慢(即使我最慢的端到端测试只有0.5秒,其中包括启动另一个JVM进程).
如果询问JVM不起作用,第三种选择是创建一个设计,在设置时跟踪所有套接字.这样做的缺点是可能会遗漏一些创建套接字的地方.由于我使用Netty,它似乎可以通过包装ChannelFactory和使用ChannelGroup来实现.
我打算使用无共享架构和多版本并发控制来创建分布式数据库系统.冗余将通过异步复制实现(只要系统中的数据保持一致,就可以在发生故障时丢失一些最近的更改).对于每个数据库条目,一个节点具有主副本(仅该节点具有对其的写访问权),此外,一个或多个节点具有该条目的辅助副本以用于可伸缩性和冗余目的(辅助副本是只读的) .更新条目的主副本时,它会加上时间戳并异步发送到具有辅助副本的节点,以便最终获得最新版本的条目.具有主副本的节点可以随时更改 - 如果另一个节点需要写入该条目,它将请求主副本的当前所有者为该节点提供该条目的主副本的所有权,
最近我一直在考虑当集群中的节点发生故障时该怎么做,以及用于故障转移的策略.这是一些问题.我希望你能知道至少其中一些的可用替代品.
我正在尝试编写单元测试以解决有关缺少stackmap帧的问题的解决方法,但为此目的,我将需要生成一个在Java 8上无法验证的类,如果它缺少stackmap帧.
下面你可以看到我的测试用例(依赖项:ASM,Guava,JUnit).它从GuineaPig类中删除了stackmap帧,希望导致其字节码无法验证.我遇到问题的部分是使用最少的代码来填充GuineaPig中的TODO,这需要堆栈图框架,以便测试通过.
import com.google.common.io.*;
import org.junit.*;
import org.junit.rules.ExpectedException;
import org.objectweb.asm.*;
import java.io.*;
import static org.objectweb.asm.Opcodes.ASM5;
public class Java6MissingStackMapFrameFixerTest {
@Rule
public final ExpectedException thrown = ExpectedException.none();
public static class GuineaPig {
public GuineaPig() {
// TODO: make me require stackmap frames
}
}
@Test
public void example_class_cannot_be_loaded_because_of_missing_stackmap_frame() throws Exception {
byte[] originalBytecode = getBytecode(GuineaPig.class);
ClassWriter cw = new ClassWriter(0);
ClassVisitor cv = new ClassVisitor(ASM5, cw) {
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, …Run Code Online (Sandbox Code Playgroud) 我对Maven的多模块项目有一个普遍的疑问.何时以及为何选择它?