小编sjl*_*lee的帖子

是否可以禁用javac的静态最终变量内联?

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的这种内联行为?对于后台,我们正在考虑进行字节码分析以实现依赖性目的,并且它是字节码分析无法检测编译时依赖性的少数情况之一.谢谢!

编辑:这是一个棘手的问题,因为通常我们不控制所有源(例如,定义常量的第三方库).我们有兴趣从使用常量的角度检测这些依赖关系.由于引用是从使用常量的代码中删除的,因此没有简单的方法来检测它们,缺少源代码分析.

java dependencies bytecode javac

53
推荐指数
4
解决办法
7453
查看次数

在eclipse中运行Java app时如何避免glob扩展

我遇到了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扩展?

java eclipse shell wildcard expansion

10
推荐指数
1
解决办法
1353
查看次数

在 github repo 的子目录中获取包

如果您有一个 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 文档,但我不清楚这是否可行。

github go

8
推荐指数
1
解决办法
2369
查看次数

当 http.Server 开始侦听时收到通知

当我查看 net/http 服务器接口时,我没有看到在 http.Server 启动并开始侦听时获得通知和反应的明显方法:

ListenAndServe(":8080", nil)
Run Code Online (Sandbox Code Playgroud)

在服务器实际关闭之前,该函数不会返回。我还查看了服务器类型,但似乎没有任何东西可以让我利用该时间。某些功能或频道本来会很棒,但我没有看到。

有什么方法可以让我检测到那个事件,还是让我只睡“足够”来伪造它?

go

6
推荐指数
1
解决办法
858
查看次数

从单个项目源构建多个jar

我相当陌生.

我想知道是否可以从同一个项目源构建多个jar.我浏览过以前类似的问题,但我的情况有点不同.我想两次编译所有源文件以生成两个不同的jar,每个jar具有不同的依赖关系,以及不同的artifact ID.从概念上讲,它可以表示如下:

  • 项目"FooBase"
    • 的src/main/JAVA/...
    • 取决于库Bar 1.0.0版
    • 编译所有源并生成"org.foo/Foo1"(组/工件)
  • 项目"Foo2"
    • 没有自己的来源,或者可能添加来源
    • 取决于库Bar 2.0.0版
    • 编译"FooBase"及其源代码中的所有源代码,并生成"org.foo/Foo2"(组/工件)

这种构建是否可以与gradle一起使用?什么是最好的方法?谢谢!

gradle

5
推荐指数
1
解决办法
2229
查看次数

标签 统计

go ×2

java ×2

bytecode ×1

dependencies ×1

eclipse ×1

expansion ×1

github ×1

gradle ×1

javac ×1

shell ×1

wildcard ×1