以下代码生成输出"Hello World!" (不,真的,试试吧).
public static void main(String... args) {
// The comment below is not a typo.
// \u000d System.out.println("Hello World!");
}
Run Code Online (Sandbox Code Playgroud)
原因是Java编译器将Unicode字符解析\u000d为新行并转换为:
public static void main(String... args) {
// The comment below is not a typo.
//
System.out.println("Hello World!");
}
Run Code Online (Sandbox Code Playgroud)
从而导致评论被"执行".
由于这可以用来"隐藏"恶意代码或恶意程序员可以设想的任何东西,为什么在评论中允许它?
为什么Java规范允许这样做?
这是一个例子:
public interface IXMLizable<T>
{
static T newInstanceFromXML(Element e);
Element toXMLElement();
}
Run Code Online (Sandbox Code Playgroud)
当然这不会奏效.但为什么不呢?
其中一个可能的问题是,当您致电时会发生什么:
IXMLizable.newInstanceFromXML(e);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我认为它应该只调用一个空方法(即{}).所有子类都将被强制实现静态方法,因此在调用静态方法时它们都会很好.那么为什么这不可能呢?
编辑:我想我正在寻找比"因为这就是Java的方式"更深层次的答案.
是否有一个特殊的技术原因导致静态方法无法被覆盖?也就是说,为什么Java的设计者决定使实例方法可覆盖但不是静态方法?
编辑:我的设计的问题是我正在尝试使用接口来强制执行编码约定.
也就是说,界面的目标是双重的:
我希望IXMLizable接口允许我将实现它的类转换为XML元素(使用多态,工作正常).
如果有人想要创建一个实现IXMLizable接口的类的新实例,他们将始终知道将有一个newInstanceFromXML(Element e)静态构造函数.
除了在界面中添加评论之外,还有其他方法可以确保这一点吗?
编辑: 从Java 8开始,接口中现在允许使用静态方法.
为什么Java不包含对无符号整数的支持?
在我看来,这是一个奇怪的遗漏,因为它们允许人们编写不太可能在意外的大输入上产生溢出的代码.
此外,使用无符号整数可以是一种自我文档形式,因为它们表明unsigned int意图保留的值绝不应该是负数.
最后,在某些情况下,无符号整数对于某些操作(例如除法)可能更有效.
包含这些内容的不利之处是什么?
在Java 8中,我可以轻松地写:
interface Interface1 {
default void method1() {
synchronized (this) {
// Something
}
}
static void method2() {
synchronized (Interface1.class) {
// Something
}
}
}
Run Code Online (Sandbox Code Playgroud)
我将获得完全同步语义,我也可以在类中使用.但是,我不能synchronized在方法声明上使用修饰符:
interface Interface2 {
default synchronized void method1() {
// ^^^^^^^^^^^^ Modifier 'synchronized' not allowed here
}
static synchronized void method2() {
// ^^^^^^^^^^^^ Modifier 'synchronized' not allowed here
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我们可以认为,这两个接口的行为方式相同,只是Interface2建立了一个合同上的method1()和method2(),这是比强一点Interface1呢.当然,我们也可能会争辩说default实现不应该对具体实现状态做出任何假设,或者这样的关键字根本不会减轻它的重量.
JSR-335专家组决定不支持synchronized接口方法的原因是什么?
在Java 8中使用默认方法作为穷人的特征是一种安全的做法吗?
一些人声称如果你只是为了它而使用它们可能会让熊猫感到悲伤,因为它很酷,但这不是我的意图.还经常提醒的是,引入了默认方法来支持API演变和向后兼容性,这是事实,但这并不会使它们错误或扭曲以将它们用作特征本身.
我有以下实际用例:
public interface Loggable {
default Logger logger() {
return LoggerFactory.getLogger(this.getClass());
}
}
Run Code Online (Sandbox Code Playgroud)
或许,定义一个PeriodTrait:
public interface PeriodeTrait {
Date getStartDate();
Date getEndDate();
default isValid(Date atDate) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
无可否认,可以使用组合(甚至是辅助类),但它看起来更冗长,更混乱,并且不允许从多态性中受益.
那么,使用默认方法作为基本特征是否可行/安全,还是应该担心不可预见的副作用?
关于SO的几个问题与Java vs Scala特征有关; 这不是重点.我也不仅仅是在征求意见.相反,我正在寻找一个权威的答案或至少是现场洞察力:如果你在公司项目中使用默认方法作为特征,那么它是否真的是一个时间炸弹?
Enum是可比较的,这意味着你可以拥有
NavigableSet<AccessMode> modes = new TreeSet<>();
NavigableMap<AccessMode, Object> modeMap = new TreeMap<>();
Run Code Online (Sandbox Code Playgroud)
它们具有O(ln N)个访问时间.
Enum集合具有O(1)访问时间,但不可导航
NavigableSet<AccessMode> modes = EnumSet.noneOf(AccessMode.class); // doesn't compile
NavigableMap<AccessMode, Object> modeMap = new EnumMap<>(AccessMode.class); // doesn't compile
Run Code Online (Sandbox Code Playgroud)
我想知道Enum集合是否不可导航(和排序)是有原因的.我错过了什么?
我们来举个例子:
public interface Testerface {
default public String example() {
return "Hello";
}
}
public class Tester implements Testerface {
@Override
public String example() {
return Testerface.super.example() + " world!";
}
}
public class Internet {
public static void main(String[] args) {
System.out.println(new Tester().example());
}
}
Run Code Online (Sandbox Code Playgroud)
简单地说,这将打印出来Hello world!.但是说我正在使用返回值做其他事情Testerface#example,例如初始化数据文件并返回一个不应离开实现类的敏感内部值.为什么Java不允许在默认接口方法上使用访问修饰符?为什么它们不能被保护/私有并且可能被子类提升(类似于扩展父类的类如何为重写方法使用更可见的修饰符)?
一个常见的解决方案是转移到抽象类,但在我的特定情况下,我有一个枚举接口,所以这里不适用.我想它或者被忽略了,或者因为接口背后的原始想法是它们是可用方法的"契约",但我想我想要输入关于这个的内容.
我读过" 为什么"最终"在Java 8接口方法中不允许? ",其中指出:
默认方法的基本思想是:它是具有默认实现的接口方法,派生类可以提供更具体的实现
对我来说听起来就像可见性根本不会破坏那个方面.
与链接的问题一样,因为它看起来很难被关闭,所以在这个问题上会得到权威的答案,而不是基于意见的答案.
回顾Java 8 StreamAPI设计,我对Stream.reduce()参数的泛型不变性感到惊讶:
<U> U reduce(U identity,
BiFunction<U,? super T,U> accumulator,
BinaryOperator<U> combiner)
Run Code Online (Sandbox Code Playgroud)
相同API的看似更通用的版本可能在个别引用上应用了协方差/逆变U,例如:
<U> U reduce(U identity,
BiFunction<? super U, ? super T, ? extends U> accumulator,
BiFunction<? super U, ? super U, ? extends U> combiner)
Run Code Online (Sandbox Code Playgroud)
这将允许以下目前无法实现的目标:
// Assuming we want to reuse these tools all over the place:
BiFunction<Number, Number, Double> numberAdder =
(t, u) -> t.doubleValue() + u.doubleValue();
// This currently doesn't work, but would work with the suggestion
Stream<Number> stream …Run Code Online (Sandbox Code Playgroud) Java 8在接口上引入了默认和静态方法.所以现在您可以在界面中使用默认或静态方法进行具体实现.
Java声称添加这两种新方法的原因是"确保与为这些接口的旧版本编写的代码的二进制兼容性".
我的问题:
在Java Interface中,我们只能使用最终变量.我们还可以在Interface中创建静态变量.但是,与此同时,我们无法创建静态/最终方法,因为接口仅适用于静态方法.
在接口中不允许静态/最终方法的原因是什么?
我正在寻找一种解决方案,它允许保护默认方法免于继承.最简单的解决方案可能是 - 从课堂等延伸......但在我的情况下,这是不可能的.
有人可以建议如何解决这个问题吗?可以有任何解决方法吗?
Atm我有以下代码,需要重新编写(如果/任何可能):
public interface MyInterface1 {
default boolean isA(Object obj) {
return (boolean) obj.equals("A") ? true : false;
}
default boolean isB(Object obj) {
return (boolean) obj.equals("B") ? true : false;
}
}
public class MyClass extends MyLogic implements MyInterface, MyInterface1 {
// this class allows to inherit methods from both interfaces,
// but from my perspective i'd like to use the methods from MyInterface1 as it is,
// with a 'protection' from inheritance. is that possible? …Run Code Online (Sandbox Code Playgroud) 我想使用java 8新的默认方法重构模板方法.假设我在抽象类中定义了一个流程:
public abstract class FlowManager{
public void startFlow(){
phase1();
phase2();
}
public abstract void phase1();
public abstract void phase2();
}
Run Code Online (Sandbox Code Playgroud)
我有几个子类扩展上面的流管理器,每个子类实现自己的phase1和phase2mathod.我想知道将代码重构为这样的接口是否有意义:
public interface FlowManager{
public default startFlow(){
this.phase1();
this.phase2();
}
public void phase1();
public void phase2();
}
Run Code Online (Sandbox Code Playgroud)
你怎么看?
Java有计划default method替代 Abstract Class吗?我找不到使用默认方法而不是抽象的真实案例?
java ×13
java-8 ×7
interface ×4
collections ×1
comments ×1
covariance ×1
enums ×1
final ×1
integer ×1
invariance ×1
java-stream ×1
jsr335 ×1
methods ×1
oop ×1
static ×1
synchronized ×1
traits ×1
unicode ×1
unsigned ×1