Tag: 语言设计

什么是“覆盖等价”,它与@Override有什么关系?

读取@Override注释的Javadoc ,我遇到了以下规则: 如果使用此注释类型注释方法,则编译器需要生成错误消息,除非至少满足下列条件之一: 该方法会覆盖或实现在超类型中声明的方法。 该方法的签名覆盖等效于Object中声明的任何公共方法。 我对第一点很清楚,但我不确定第二点。 “覆盖等价”是什么意思? 在这方面, Object公共方法如何特殊? 为什么这不属于第一个标准? 更新说明:这仅适用于Java 7文档。 Java 6 doc没有提到有关覆盖等价的任何内容。 为什么要改变? 更新: 在咨询了JLS( 第8.4.2节 )之后,我发现了以下对覆盖等价的解释: 方法m1的签名是方法m2的签名的子签名,如果: m2与m1具有相同的签名,或 m1的签名与m2签名的擦除( §4.6 )相同。 如果m1是m2签名或m2是m1签名,则两个方法签名m1和m2是覆盖等价的 。 据我所知,这回答了第一个问题(“它是什么意思?”)和第三个问题(“为什么第一个条件不包括这个?”)。 如果我理解正确(如果我不理解,请通知我!),只有一种情况,两种方法是覆盖等价的, 并且不属于原始问题的第一个条件。 当子类方法的签名的擦除与超类方法的签名相同时,情况就是这种情况,而不是相反。 因此,当我们在尝试“覆盖” Object类的公共方法时尝试添加类型参数时,原始问题的第二个条件才会发挥作用。 我尝试了以下简单示例来测试它,使用未使用的类型参数: public class Foo { @Override public boolean equals(Object obj) { return true; } } 当然,这个类不编译,因为该方法实际上并没有覆盖equals方法,因此与它发生冲突。 但是我仍然收到使用@Override注释的错误。 假设这是@Override使用的第二个条件的有效示例,我错了吗? 或者编译器是否生成此错误, 尽管不需要 ?

在Java中,在generics类型的实例上调用getClass时如何避免原始类型?

假设我在Java中有这个: List list = new ArrayList(); list.getClass(); 最后一个表达式的类型是Class Class 。 我理解为什么,由于擦除,它不能是Class<? extends List> Class<? extends List> 。 但为什么不能成为Class<? extends List> Class<? extends List> ? 如果我想将这个表达式的结果分配给一个变量,以某种方式保存这个类实际上是某种List的信息,我是否有办法避免未经检查的强制转换警告和原始类型警告 ? Class listClass = list.getClass(); // raw type warning Class<? extends List> listClass = (Class<? extends List>) list.getClass(); // unchecked cast warning

为什么java没有字节类型后缀?

所以java的文字后缀为long类型:(123L),双类型后缀(43.21D),浮点后缀(1.234F)。 那么……为什么没有字节类型后缀? 例如,在编写一些测试代码时,必须在将它们用作函数参数时转换所有字节。 ByteBuffer b = ByteBuffer.allocate(100); b.put((byte)3); // super annoying b.put(3b); // if only 很明显,使用B或b是行不通的,因为它会与以hex或八进制(一种关键语言特征)指定字节的能力相冲突。 但是其他一些字母,比如Z z? 或Y y(对于bYte)?

清空if语句

通过“空if语句”,我的意思是这样的(注意分号): if (condition); 我很难想到这个应用程序。 使用while循环,您可以执行以下操作: while (callUntilReturnsFalse()); 但是if语句没有这样的申请。 更重要的是,Java编译器在面对这样的语句时不会发出错误或警告。 这可能会导致大而沉默的问题,特别是有一个漫长而复杂的陈述: if ((functionA() && functionB(getFoo()) || checkForComplexCondition(arg1, arg2, getBar(getFoo()))); { doStuff(); } 我的问题是:为什么Java允许这样做? 而且,更重要的是,我可以启用一个选项,以便在发生这种情况时发出警告吗? ( 之前就C# 提出了这个问题,它确实发出警告,但我希望找到一种方法来引发Java警告。)

在Java上使用DSL的第一步?

伙计们……女孩们,我正在研究一个项目,我认为可以通过实施领域特定语言来为某种类型的工作流程定义一套规则和/或条件来加强这个项目。 我希望能够牢牢掌握主题,基础知识,最佳实践等,特别是如何使用Java以某种方式实现它们。 你有什么建议?

有没有更优雅的方式来处理Java中的列表? (Python VS Java)

我喜欢用Python处理列表的方式。 它做任何递归解决方案看起来容易和干净。 例如,在Python中获取元素的所有排列的典型问题如下所示: def permutation_recursion(numbers,sol): if not numbers: print “this is a permutation”, sol for i in range(len(numbers)): permutation_recursion(numbers[:i] + numbers[i+1:], sol + [numbers[i]]) def get_permutations(numbers): permutation_recursion(numbers,list()) if __name__ == “__main__”: get_permutations([1,2,3]) 我喜欢通过像numbers[:i] + numbers[i+1:]或sol + [numbers[i]]这样简单地获取修改列表的新实例的方式 如果我尝试在Java中编写完全相同的代码,它看起来像: import java.util.ArrayList; import java.util.Arrays; class rec { static void permutation_recursion(ArrayList numbers, ArrayList sol) { if (numbers.size() == […]

为什么Java允许在任意语句上标记中断?

我今天刚刚了解到以下Java代码是完全合法的: myBlock: { /* … code … */ if (doneExecutingThisBlock()) break myBlock; /* … more code … */ } 请注意, myBlock不是一个循环 – 它只是一个我用花括号分隔的代码块。 这似乎是一个相当奇怪的特征。 这意味着您可以使用命名break来突破if语句或匿名块,但通常不能在这些上下文中使用break语句。 我的问题是: 这个设计决定有充分的理由吗? 也就是说,为什么要这样做,你只能使用带标签的break而不是常规break来break某些封闭语句? 为什么要允许这种行为呢? 鉴于(相对)精心设计的Java如何作为一种语言,我认为这是有原因的,但我真的想不到一个。

私有内部类的默认构造函数是否具有forms参数?

警告#1:这实际上是一个潜在的两个部分:首先,私有内部类的构造函数是否具有forms参数? 如果是的话,为什么JLS说不呢? 如果不是,怎么/为什么不呢? 警告#2: 这个问题不是为了推测。 我只是在寻找权威的答案。 默认构造函数在JLS 8.8.9中定义,它声明(部分): 默认构造函数没有forms参数,除非在非私有内部成员类中,默认构造函数隐式声明一个forms参数,表示该类的直接封闭实例(§8.8.1,§15.9.2,§15.9.3) )。 (重点补充) “非私有”位对我来说似乎很奇怪:为了让内部类访问其封闭类中定义的字段,它需要对该实例的引用。 无论内部类是否为私有,这都应该是相同的。 事实上,javac似乎与我一致,与规范相矛盾。 如果我编译这个: public class Ctors { private class MyInner { } } …并运行javap -c -private ,然后我们看到一个带有单个forms参数的构造函数,用于封闭类的实例: $ javap -c -private Ctors\$MyInner Compiled from “Ctors.java” class Ctors$MyInner { final Ctors this$0; private Ctors$MyInner(Ctors); Code: 0: aload_0 1: aload_1 2: putfield #1 // Field […]

支持goto的Java编译器或JVM语言?

是否有一个java编译器标志允许我使用goto作为有效的构造? 如果没有,是否有支持goto的第三方java编译器? 如果没有,是否有任何其他支持goto语言,同时可以轻松调用用Java编写的方法? 原因是我正在制作一种用Java实现的语言。 Gotos是我语言的重要组成部分; 我希望能够将其编译为本机或JVM字节码,尽管它必须能够轻松使用Java库(即.C支持goto ,但要使用它我必须在C中重写库)。 我想生成C或Java等源文件,而不是字节码或机器代码。 我正在使用第三方编译器来做到这一点。

为什么Java使用-D来表示系统属性?

为什么标志指示Java -D的System属性? 当然这个字母选择有一些语义,但我猜不出它是什么。