小编Seb*_*iot的帖子

如何在Java"注释处理器"中处理泛型?

我之前问过一个例子"注释处理器",它会为一个接口生成一个代理/代理,但没有得到答案,也没有在互联网上找到任何东西,所以我自己做了.

到目前为止它运行良好,直到我尝试在超级界面中使用泛型.如果我在带注释的界面中使用泛型,它可以正常工作(更多是偶然而非设计).但是,如果带注释的接口扩展了另一个采用泛型类型参数的接口,则该参数不会"绑定"到注释接口在扩展超级接口时使用的类型.例:

public interface TestFragment<E> {
    void test(E dummy);
}
@CreateWrapper
public interface TestService extends TestFragment<String> {
    double myOwnMethod();
}
Run Code Online (Sandbox Code Playgroud)

这会产生:

// ...
public void test(final E dummy) {
    wrapped.test(dummy);
}
// ...
Run Code Online (Sandbox Code Playgroud)

而不是正确的:

// ...
public void test(final String dummy) {
    wrapped.test(dummy);
}
// ...
Run Code Online (Sandbox Code Playgroud)

在生成的方法中生成参数的代码如下所示:

int count = 0;
for (VariableElement param : method.getParameters()) {
    if (count > 0) {
        pw.print(", ");
    }
    count++;
    pw.printf("final %s %s", param.asType().toString(),
        param.getSimpleName().toString());
}
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?

java generics annotations

7
推荐指数
2
解决办法
3435
查看次数

如何在范围搜索中使用Morton Order?

如果我有一个数据集,其中键是3D中的点,由3个带符号的64位整数表示.我想使用(排序的)键值存储来存储它们,其中键只是字节数组(但我可以指定一个比较器).我想我可以通过使用位交错将所有这些点转换为字节数组,就像在Z/Morton命令中一样,如在如何计算3D Morton数中那样

除了获取单个点,这可以更简单地完成而无需Morton排序,我想做范围搜索,我在一个与轴对齐的框中搜索.我将A和B分别定义为所有坐标最低的方框角,以及所有坐标最高的对角.

现在我的问题是:

  1. 对于在逻辑上介于A和B之间的任何点C,C的Morton数也将介于A和B的Morton数之间吗?(这不是莫顿的命令吗?)

  2. 如果1为否,A和B是否可以"舍入"到保证包含C的值?

  3. 假设1或2是可能的,搜索返回也指向该框之外,我必须"后过滤"了吗?"错误集"有多大(它取决于搜索的大小或位置)?

  4. 整数是否签名的事实会导致问题吗?如果是这样,是否有解决方法?

回顾一下,使用Morton Numbers只是实际问题的一种可能解决方案:当3D点必须映射到一维值时,如何有效地在3D整数空间中进行范围搜索?我希望通过在数据库中执行单个范围选择,使用最小键和最大键来获得A和B之间的所有点,理想情况下,尽可能少地获取框外的点.

algorithm search bit-manipulation range z-order-curve

7
推荐指数
2
解决办法
3641
查看次数

Clang比平台上的GCC更具确定性吗?

我正在考虑用C++编写多用户R​​TS游戏(部分)的可行性.我很快发现,一个硬性要求是游戏模拟必须对服务器和所有客户端的最后一点完全确定,以便能够将网络通信限制为用户输入,而不是游戏状态本身.由于每个人都有不同的计算机,这似乎是一个难题.

那么,是否有一些"神奇"的方法让C++编译器创建一个可在Linux(服务器),Windows和Mac上完全确定的可执行文件?我认为两个主要的OSS C++编译器是GCC和Clang,所以我想知道在这方面一个是否比另一个表现更好.

我也对任何可用于验证C++确定性的测试套件感兴趣.

[编辑]通过确定性,我的意思是编译的程序,给定相同的初始状态,并以相同的顺序输入,将始终在其运行的任何平台上产生相同的输出.所以,也是整个网络.一致的声音对我来说是对这种行为的恰当定义,但我不是母语人士,所以我可能会误解其确切含义.

[编辑#2]虽然关于确定性/一致性是否重要,以及我是否应该在游戏引擎中实现这一目标的讨论,以及它在C++中通常存在多大问题,但是它非常有趣,它实际上并没有真正回答题.到目前为止,没有人告诉我是否应该使用Clang或GCC来获得最可靠/确定/一致的结果.

[编辑#3]我刚想到有一种方法可以在Java中获得与C++完全相同的结果.必须采用JVM的开源实现,并提取实现运算符和数学函数的代码.然后将其转换为独立库并在其中调用可内联函数,而不是直接使用运算符.手动完成会很痛苦,但如果生成代码,那么这是一个完美的解决方案.也许这甚至可以通过类和运算符重载来完成,所以它看起来也很自然.

c++ cross-platform deterministic

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

那里有Java flyweight模式实现吗?

我一直在寻找一个flyweight模式实现,并在达到Google搜索的第20页后放弃了.虽然有无数愚蠢的例子,但似乎没有人发表过Java中可重用的实现.

对我来说,如果你必须保留很多这样的实例,flyweight真的才有意义,所以它必须作为一个集合来实现.我想要的是一个Factory,它接受一个byte/short/int/long 映射器实现,并返回一个List,Set或Map,它看起来像一个普通的Object集合,但是在内部将它的数据存储为一个原语数组,从而节省了很多公羊.映射器将采用类型为X的对象,并将其映射到基元,或者以相反的方式执行.

在某个地方有类似的东西吗?

[编辑]我正在寻找一个支持这种模式的Collection库,而不仅仅是任何一个例子,其中有数百个.

java design-patterns flyweight-pattern

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

是否可以在Scala中更改基类/特征的方差?

我想从Scala的不可变映射派生出来.它定义如下:

trait Map[A, +B]
Run Code Online (Sandbox Code Playgroud)

不幸的是,我的实现需要在B中保持不变.我尝试了以下内容,但没有成功:

def +(kv : (A, B)) : MyMap[A, B] = { ... }

override def +[B1 >: B](kv : (A, B1)) : MyMap[A, B1] =
    throw new IllegalArgumentException()
Run Code Online (Sandbox Code Playgroud)

也许有一招@uncheckedVariance

scala variance

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

当Scala类型参数用作基类的参数时,它是否可以引用自身?

如果我有以下Scala类型层次结构:

// Base traits
trait TA[X <: TA[X,Y], Y <: TB[X,Y]]
trait TB[X <: TA[X,Y], Y <: TB[X,Y]]
trait TC[X <: TA[X,_]]

// More specific traits
trait TI[X <: TI[X,Y], Y <: TJ[X,Y]] extends TA[X,Y]
trait TJ[X <: TI[X,Y], Y <: TJ[X,Y]] extends TB[X,Y]
trait TK[X <: TI[X,_]] extends TC[X]

// Concrete class that should implement TK, but does not compile
class Z extends TK[TI[_,_]]

// What is needed to be able to get class Z to compile
// The …
Run Code Online (Sandbox Code Playgroud)

generics scala

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

如果安装了Java 8,则无法使用Java 7安装

我通常仍然将Java 7用于我的所有编码项目(这是一个公司"政治"问题),但我为一个我正在贡献的第三方项目安装了Java 8.现在,似乎我不能在Windows 7 x64中安装Java 8,并且默认情况下仍然使用Java 7:

C:\>"%JAVA_HOME%\bin\java.exe" -version
java version "1.7.0_55"
Java(TM) SE Runtime Environment (build 1.7.0_55-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.55-b03, mixed mode)

C:\>java.exe -version
java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)
Run Code Online (Sandbox Code Playgroud)

如您所见,JAVA_HOME完全被忽略.

我在路径中也有Java,使用"%JAVA_HOME%\ bin",当我检查DOS框中的路径时,它正确地解析为Java 7,但它仍然没有区别.

我检查了"Java控制面板"(不确定这是否会影响默认的命令行Java版本).在"Java"选项卡的"View ..."按钮下,您可以看到"已注册"的Java版本.我可以在"用户"选项卡下添加所有版本,但在"系统"下只有Java 8,无法更改它.

我是否遗漏了一些东西,或者甲骨文是否只是不可能使用Java 7,除非我卸载Java 8?我不想在任何地方指定"源"和"目标",我甚至不知道是否可以在任何地方指定它,使用Java.

编辑:我做的是我卸载所有Java.然后安装最新的Java7(86和x64),然后安装最新的Java8(86和x64).在我这样做之后,我注意到x64 JDK 已经消失了.似乎Java8杀了它.所以我在JDK 8 x64 之后重新安装了JDK 7 x64.尽管如此,JDK7 x64似乎并没有"替换"复制到"Windows"目录本身的"java.exe"(我假设这是问题所在).

java windows

6
推荐指数
2
解决办法
2万
查看次数

构造函数中的自引用是否算作"转义"?

阅读有关JSR-133的这篇文章,它说:

所有对最终字段的写入(以及通过这些最终字段间接到达的变量)都会变为"冻结",......

如果在构造期间不允许对象的引用转义,那么一旦构造函数完成并且线程发布对对象的引用,该对象的最终字段将保证可见...

初始化安全性的一个警告是,对象的引用不得"转义"其构造函数 - 构造函数不应直接或间接地发布对正在构造的对象的引用.

我的问题是关于什么被认为是逃避.更具体地说,我想知道这个(有点人为和​​奇怪的)代码是否会产生一个安全可发布的Child对象:

class Parent {
    /** NOT final. */
    private int answer;

    public int getAnswer() {
        return answer;
    }

    public void setAnswer(final int _answer) {
        answer = _answer;
    }
}

public class Child extends Parent {
    private final Object self;

    public Child() {
        super.setAnswer(42);
        self = this;
    }

    @Override
    public void setAnswer(final int _answer) {
        throw new UnsupportedOperationException();
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 首先,虽然Parent显然是可变的,但Child是"有效不可变的",因为允许可变性的父设置器不再可用.
  2. 构造函数中对"this"的引用对任何人都不可见(不是getter,也不会传递给任何其他对象).那么,这算是"逃避"吗?
  3. 但是整个对象被最终字段(自我)引用,因此理论上,它的整个内容应该被"冻结".OTOH,最终的领域本身是无法到达的,所以也许它不算数; 我完全可以想象JIT只是完全优化它.
  4. 如果通过getter可以访问"self",但是在构造函数中没有调用getter,那么它是否算作转义(假设之前没有)?这会阻止JIT优化它,所以它必须"计数",也许?

那么,儿童是"安全可发布的",如果没有,为什么,并且"自我"的吸气者会改变答案吗?

如果问题的目的不明确,我认为如果这有效,它将允许人们轻松地将一个可变类"安全地发布",只需如上所示扩展它.

java constructor

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

我可以在没有条件的Java中创建1到64位的位掩码吗?

我想编写一个函数,它接受1到64之间的int,并返回一个适当的"位掩码",输入为1位.

我开始是这样的:

/** Computes a bitmaks */
private static long mask(final int bitsPerValue) {
    return (1L << bitsPerValue) - 1L;
}
Run Code Online (Sandbox Code Playgroud)

但意识到它为64提供了错误的值:

(1L << 64) - 1L == 1L - 1L == 0
Run Code Online (Sandbox Code Playgroud)

现在我有这个:

/** Computes a bitmaks */
private static long mask(final int bitsPerValue) {
    return (bitsPerValue == 64) ? -1 : ((1L << bitsPerValue) - 1L);
}
Run Code Online (Sandbox Code Playgroud)

这很难看.条件可以改变控制流程,因此它们比简单的算术运算更昂贵.我可以预先计算掩码并将它们放在静态数组中,但是数组访问也比简单的算术运算更昂贵,可能比条件更昂贵.

是否有合理的方式在没有条件的情况下写这个?这段代码将每秒运行数万亿次,因此必须快速.

java bitmask

5
推荐指数
2
解决办法
1922
查看次数

如何在隐式长到双转换时产生编译错误?

当"long"被隐式转换为"double"时,有没有办法让Java编译器产生错误,因为这会导致数据丢失?

编辑:我不能接受亚历克斯的答案的原因是它击败了我的目的.我想要做的是创建一个最小的 "functor"API,它不会通过直接支持原始类型而导致垃圾,而不是仅使用泛型支持对象类型.但是为了保持接口数量少,我想尽量少使用类型.只有double和Object,对于参数和返回值,我支持(几乎)所有类型而不会导致垃圾,也不会丢失任何数据(布尔值不会转换为double,但也不会因autoboxing而导致垃圾,AFAIK,所以没关系明确地支持它).由于除boolean和long之外的所有原始类型都可以安全地和隐式地转换为double,因此我几乎满足了所有需求.

这就是问题的来源:如果我不在API中添加明确的支持,如何防止长期使用,因为它会导致错误?当然,使用java.lang.Double而不是double会导致垃圾,因此使API变得毫无意义.

在有人要求之前,我会说我想在实时Android游戏中使用API​​,其中"垃圾"是一个真正的问题,与JVM不同.

java double long-integer

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