Java静态编译器(javac)内联一些静态最终变量,并将值直接带到常量池.请考虑以下示例.A类定义了一些常量(公共静态最终变量):
public class A {
public static final int INT_VALUE = 1000;
public static final String STRING_VALUE = "foo";
}
Run Code Online (Sandbox Code Playgroud)
B类使用以下常量:
public class B {
public static void main(String[] args) {
int i = A.INT_VALUE;
System.out.println(i);
String s = A.STRING_VALUE;
System.out.println(s);
}
}
Run Code Online (Sandbox Code Playgroud)
编译类B时,javac从类A获取这些常量的值,并在B.class中内联这些值.结果,编译时必须从A类中删除的依赖关系B从字节码中删除.这是一种相当奇特的行为,因为您在编译时正在烘焙这些常量的值.你会认为这是JIT编译器在运行时可以做的最容易的事情之一.
是否有任何方法或任何隐藏的编译器选项可以禁用javac的这种内联行为?对于后台,我们正在考虑进行字节码分析以实现依赖性目的,并且它是字节码分析无法检测编译时依赖性的少数情况之一.谢谢!
编辑:这是一个棘手的问题,因为通常我们不控制所有源(例如,定义常量的第三方库).我们有兴趣从使用常量的角度检测这些依赖关系.由于引用是从使用常量的代码中删除的,因此没有简单的方法来检测它们,缺少源代码分析.
我遇到了Eclipse运行配置的特殊行为,它似乎只是一个Windows问题.假设我有一个Java应用程序打印出命令行参数,如下所示:
public class WildCard {
public static void main(String[] args) {
for (String arg: args) {
System.out.println(arg);
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我使用可以由shell扩展的外卡提供参数,shell将展开它并将其提供给Java程序.这并不奇怪.所以,如果我在命令提示符下做
java WildCard test/*
Run Code Online (Sandbox Code Playgroud)
该程序将打印
test/foo.txt
test/bar.txt
Run Code Online (Sandbox Code Playgroud)
其中foo.txt和bar.txt是目录"test"中的文件.
如果我用引号括起通配符参数,可以防止Shell扩展;*nix上的单引号,以及Windows上的双引号.所以对于Windows,如果我在命令提示符下执行以下操作:
java WildCard "test/*"
Run Code Online (Sandbox Code Playgroud)
该程序现在将打印
test/*
Run Code Online (Sandbox Code Playgroud)
(没有扩张).
但是,我发现Eclipse运行启动器中的引用似乎没有效果,并且参数仍在扩展.如果我放
"test/*"
Run Code Online (Sandbox Code Playgroud)
在Eclipse运行启动程序的程序参数部分,并运行上面的类,我仍然得到
test/foo.txt
test/bar.txt
Run Code Online (Sandbox Code Playgroud)
换句话说,当程序实际运行时,双引号似乎丢失了.这似乎只发生在Windows上.
有没有办法在Windows上使用Eclipse运行启动器阻止glob扩展?
如果您有一个 go-only 存储库(假设它是https://github.com/foo/bar),您可以将您的代码放在根级别,并使用以下命令导入其他代码:
go get -u github.com/foo/bar
Run Code Online (Sandbox Code Playgroud)
其中的目录和子目录将被识别为包。
但是假设您正在 github 上创建一个多语言存储库(例如,一个具有 java 代码、go 代码、javascript 代码等)。并且你想让你的 go 代码可供其他人使用。从代码组织的角度来看,通常将 go 代码放在根级别是不可以的。可能更常见的是
(root)
|-- src
|-- main
|-- go
|-- java
|-- javascript
|-- proto
Run Code Online (Sandbox Code Playgroud)
Go 代码的根级别现在位于https://github.com/foo/bar/src/main/go。但是您不能再使用以前的go get命令,因为它会查看顶层。您真的不想使用它们go get -u github.com/foo/bar/src/main/go,因为所有这些现在都将成为包名称的一部分,这真是令人讨厌。
问题是,有没有办法指定一个确切的 URL,以便您可以将包名和 URL 分开?换句话说,我正在寻找类似的东西
go get -u github.com/foo/bar https://github.com/foo/bar/src/main/go
Run Code Online (Sandbox Code Playgroud)
(当然,包名应该与源代码中实际存在的包名相匹配,否则将无法编译)。
我查看了 go 文档,但我不清楚这是否可行。
当我查看 net/http 服务器接口时,我没有看到在 http.Server 启动并开始侦听时获得通知和反应的明显方法:
ListenAndServe(":8080", nil)
Run Code Online (Sandbox Code Playgroud)
在服务器实际关闭之前,该函数不会返回。我还查看了服务器类型,但似乎没有任何东西可以让我利用该时间。某些功能或频道本来会很棒,但我没有看到。
有什么方法可以让我检测到那个事件,还是让我只睡“足够”来伪造它?
我相当陌生.
我想知道是否可以从同一个项目源构建多个jar.我浏览过以前类似的问题,但我的情况有点不同.我想两次编译所有源文件以生成两个不同的jar,每个jar具有不同的依赖关系,以及不同的artifact ID.从概念上讲,它可以表示如下:
这种构建是否可以与gradle一起使用?什么是最好的方法?谢谢!