相关疑难解决方法(0)

为什么在允许某些Unicode字符的注释中执行Java代码?

以下代码生成输出"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规范允许这样做?

java unicode comments

1326
推荐指数
7
解决办法
7万
查看次数

为什么我不能在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的设计者决定使实例方法可覆盖但不是静态方法?

编辑:我的设计的问题是我正在尝试使用接口来强制执行编码约定.

也就是说,界面的目标是双重的:

  1. 我希望IXMLizable接口允许我将实现它的类转换为XML元素(使用多态,工作正常).

  2. 如果有人想要创建一个实现IXMLizable接口的类的新实例,他们将始终知道将有一个newInstanceFromXML(Element e)静态构造函数.

除了在界面中添加评论之外,还有其他方法可以确保这一点吗?

编辑: 从Java 8开始,接口中现在允许使用静态方法.

java static-methods interface

480
推荐指数
10
解决办法
33万
查看次数

为什么Java不支持无符号整数?

为什么Java不包含对无符号整数的支持?

在我看来,这是一个奇怪的遗漏,因为它们允许人们编写不太可能在意外的大输入上产生溢出的代码.

此外,使用无符号整数可以是一种自我文档形式,因为它们表明unsigned int意图保留的值绝不应该是负数.

最后,在某些情况下,无符号整数对于某些操作(例如除法)可能更有效.

包含这些内容的不利之处是什么?

java unsigned integer language-design

367
推荐指数
11
解决办法
11万
查看次数

在Java 8接口方法中不允许"synchronized"的原因是什么?

在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 synchronized java-8 jsr335 default-method

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

Java 8默认方法作为特征:安全吗?

在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特征有关; 这不是重点.我也不仅仅是在征求意见.相反,我正在寻找一个权威的答案或至少是现场洞察力:如果你在公司项目中使用默认方法作为特征,那么它是否真的是一个时间炸弹?

java traits java-8 default-method

115
推荐指数
1
解决办法
1万
查看次数

是否有任何原因EnumMap和EnumSet不可导航

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集合是否不可导航(和排序)是有原因的.我错过了什么?

java collections enums

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

为什么Java 8不允许使用非公共默认方法?

我们来举个例子:

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 java-8 default-method

31
推荐指数
1
解决办法
5624
查看次数

在Stream.reduce()这样的API中选择不变性有什么好理由?

回顾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 covariance contravariance java-stream invariance

20
推荐指数
1
解决办法
454
查看次数

在接口中添加默认和静态方法的原因

Java 8在接口上引入了默认和静态方法.所以现在您可以在界面中使用默认或静态方法进行具体实现.

Java声称添加这两种新方法的原因是"确保与为这些接口的旧版本编写的代码的二进制兼容性".

我的问题:

  • 为什么要扭曲界面原始概念,假设是完全抽象的,以支持现有的架构问题?
  • 除了类扩展多个接口的能力之外,使用抽象类和接口的新版本有什么区别?

java oop interface java-8

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

为什么接口方法不能"静态"和"最终"?

在Java Interface中,我们只能使用最终变量.我们还可以在Interface中创建静态变量.但是,与此同时,我们无法创建静态/最终方法,因为接口仅适用于静态方法.

在接口中不允许静态/最终方法的原因是什么?

java methods static final interface

7
推荐指数
3
解决办法
3万
查看次数

保护"默认"方法不要覆盖

我正在寻找一种解决方案,它允许保护默认方法免于继承.最简单的解决方案可能是 - 从课堂等延伸......但在我的情况下,这是不可能的.

有人可以建议如何解决这个问题吗?可以有任何解决方法吗?

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 java-8

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

使用Java 8的模板方法设计模式

我想使用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)

我有几个子类扩展上面的流管理器,每个子类实现自己的phase1phase2mathod.我想知道将代码重构为这样的接口是否有意义:

public interface FlowManager{
    public default startFlow(){
        this.phase1();
        this.phase2();
    }
    public void phase1();
    public void phase2();
}
Run Code Online (Sandbox Code Playgroud)

你怎么看?

java design-patterns java-8 default-method

4
推荐指数
1
解决办法
4801
查看次数

Java是否计划使用默认方法(java8)替代抽象类?

Java有计划default method替代 Abstract Class吗?我找不到使用默认方法而不是抽象的真实案例?

java abstract-class interface java-8 default-method

2
推荐指数
4
解决办法
625
查看次数