标签: default-method

Java默认方法-获取子类的类型

我有一个接口,我想在其中提供默认方法来序列化继承的类。我使用一个JsonSerializer<T>类来进行序列化。

该方法如下所示:

public interface A
{
    public default String write()
    {
        new JsonSerializer</*Inherited class type*/>();
        // I've tried new JsonSerializer<this.getClass()>();  - Doesn't work

    }
}

public class AX implements A
{
}
Run Code Online (Sandbox Code Playgroud)

所以当我实例化AX时,我想使用write方法来序列化AX

AX inst = new AX();
String instSerialized = inst.write();
Run Code Online (Sandbox Code Playgroud)

我需要将 AX 的类型传递给 A 中的 write 方法。这可能吗?

java generics default-method

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

为什么Java 8没有将`withLock`默认方法添加到`java.util.concurrent.locks.Lock`接口?

这个问题一样,我想知道为什么Java团队没有为Lock接口添加一些默认方法,如下所示:

public default void withLock(Runnable r) {
  lock();

  try {
     r.run();
  } finally {
     unlock();
  }
}
Run Code Online (Sandbox Code Playgroud)

这将允许程序员这样做

public class ThreadSafe {
  // Object requiring protection
  private final List<String> l = new ArrayList<>();
  private final Lock lock = new ReentrantLock();

  public void mutate(String s) {
    lock.withLock(() -> l.add(s));
  }

  public void threadSafeMethod {
    lock.withLock(() -> { System.out.println(l.get(l.size())); });
  }
}
Run Code Online (Sandbox Code Playgroud)

代替

public void threadSafeMethod {
  lock.lock();
  try {
    System.out.println(l.get(l.size())); 
  } finally { 
    lock.unlock();
  }
}
Run Code Online (Sandbox Code Playgroud)

locking java-8 default-method

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

Java 8默认接口方法上的Spring Integration @ServiceActivator

我想@ServiceActivator在Java 8默认接口方法上使用注释.此默认方法将根据业务规则委托此接口的另一个方法.

public interface MyServiceInterface {

    @ServiceActivator
    public default void onMessageReceived(MyPayload payload) {
        if(payload.getAction() == MyServiceAction.MY_METHOD) {
            ...
            myMethod(...);
        }
    }

    public void myMethod(...);
}
Run Code Online (Sandbox Code Playgroud)

然后,此接口由Spring @Service类实现:

@Service
public class MyService implements MyServiceInterface {

    public void myMethod(...) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

执行代码时,这不起作用!

我只能让它@ServiceActivator从默认方法中删除注释,并覆盖我的@Service类中的默认方法并委托给super方法:

@Service
public class MyWorkingService implements MyServiceInterface {

    @ServiceActivator
    @Override
    public void onMessageReceived(MyPayload payload) {
        MyServiceInterface.super.onMessageReceived(payload);
    }

    public void myMethod(...) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

覆盖默认方法会忽略默认方法的用途.

是否有其他方式以干净的方式实现此方案?

java spring spring-integration java-8 default-method

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

接口中的默认方法,但只有静态最终字段

我知道Inteface 中的所有字段都是隐式静态和最终的.这在Java 8之前就有意义了.

但是随着默认方法的引入,接口也具有抽象类的所有功能.因此,非静态和非最终字段也是必要的.

但是当我尝试正常声明一个字段时,它默认变为静态和最终.

有没有办法在Java 8中的Interface中声明非静态和非final字段.

或者我在这里完全误解了什么?

java default-method

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

阴影接口的默认方法

考虑以下情况,

interface IFace1 {
    default void printHello() {
        System.out.println("IFace1");
    }
}

interface IFace2 {
    void printHello();
} 

public class Test implements IFace1, IFace2 {

    public static void main(String[] args) {
        Test test = new Test();
        test.printHello();

        IFace1 iface1 = new Test();
        iface1.printHello();

        IFace2 iface2 = new Test();
        iface2.printHello();
    }

    @Override
    public void printHello() {
        System.out.println("Test");
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我得到了非常期待的输出.

Test
Test
Test
Run Code Online (Sandbox Code Playgroud)

我一直在阅读有关Java-8默认方法的内容,特别是有关扩展包含默认方法的接口的内容

2 nd bullet:重新声明默认方法,使其成为抽象方法.

在上面的例子中,我有这有相同名称的默认方法两个接口,当我实现了这两个我才能够达到执行printHelloTest是指IFace2.

我对此几乎没有疑问, …

java java-8 default-method

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

在这个Java示例中对"super"关键字感到困惑

在java网站的教程页面上的这个例子中.两个接口定义相同的默认方法startEngine().类FlyingCar实现两个接口,并且必须覆盖,startEngine()因为存在明显的冲突.

public interface OperateCar {
    // ...
    default public int startEngine(EncryptedKey key) {
        // Implementation
    }
}
public interface FlyCar {
    // ...
    default public int startEngine(EncryptedKey key) {
        // Implementation
    }
}

public class FlyingCar implements OperateCar, FlyCar {
    // ...
    public int startEngine(EncryptedKey key) {
        FlyCar.super.startEngine(key);
        OperateCar.super.startEngine(key);
    }
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么,from FlyingCar,super用于指代startEngine()in OperateCarFlyCarinterfaces的两个版本.据我所知,startEngine()没有在任何超类中定义,因此不应该被称为居民.我也没有看到super和实现的两个接口之间有任何关系FlyingCar

java interface super java-8 default-method

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

java接口中的默认方法是反模式吗?

Java 8 在接口上引入了默认方法,为集合接口的实现提供向后兼容性,以避免遗留库上出现 MethodNotFound 错误。

即具有List 的java 7 实现的库将不会实现stream() 方法。如果 java 8 代码使用此库,则默认实现会提供后备方案。

我在实践中看到的是,许多开发人员过度热衷于使用此功能以类似于 scala 特征的风格来模拟混合和多重继承。

我担心的一个问题是,这种编程风格模糊了接口(即契约)及其实现之间的界限,因此引入了隐藏的紧密耦合并违反了控制反转,迫使我使用后门通过覆盖默认实现来测试代码。我的单元测试,以抑制不应出现在单元测试级别的行为。

使用默认方法是一种反模式,还是只有我一个人怀疑这一点?

anti-patterns inversion-of-control mixins java-8 default-method

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

Getter在默认方法JSF的接口中

我有一个具有以下默认方法的接口:

default Integer getCurrentYear() {return DateUtil.getYear();}
Run Code Online (Sandbox Code Playgroud)

我还有一个实现此接口的控制器,但它不会覆盖该方法.

public class NotifyController implements INotifyController
Run Code Online (Sandbox Code Playgroud)

我试图从我的xhtml访问此方法,如下所示:

#{notifyController.currentYear}
Run Code Online (Sandbox Code Playgroud)

但是,当我打开屏幕时,会出现以下错误:

The class 'br.com.viasoft.controller.notify.notifyController' does not have the property 'anoAtual'
Run Code Online (Sandbox Code Playgroud)

如果我从我的控制器的实例访问此方法,它返回正确的值,但是当我尝试从我的xhtml访问它作为"属性"时,它会发生此错误.

有没有办法从我的控制器的引用访问此接口属性,而无需实现该方法?

jsf el java-8 default-method propertynotfoundexception

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

Java 8 中的接口隔离原则和默认方法

根据接口隔离原则

不应该强迫客户端实现不需要的接口方法

...因此我们应该定义接口以进行逻辑分离。

但是defaultJava 8 中引入的方法提供了在 Java 接口中实现方法的灵活性。似乎 Java 8 提供了增强接口的可行性,使其具有一些与其核心逻辑无关的方法,但具有一些默认或空的实现。

它不违反ISP吗?

java solid-principles default-method interface-segregation-principle

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

在 Android 发布版本中使用默认方法会引发 AbstractMethorError

我有一个从 Android 继承的接口,TextWatcher仅用于实现afterTextChanged方法。我在我的项目中启用了 Java 8 支持,并在build.gradle文件中添加了源和目标兼容性选项,但即使它在调试版本中运行完美,它在我测试的每台设备上的发布版本中都失败了。我首先在 Play Console 的预发布报告中注意到了它,并在 Firebase 的测试实验室中再次进行了测试,但仍然是每次设备抛出AbstractMethodError后都会崩溃。

这是我的AfterTextChangedListener

import android.text.Editable;
import android.text.TextWatcher;

public interface AfterTextChangedListener extends TextWatcher {
    @Override
    default void beforeTextChanged(CharSequence s, int start, int count, int after) {
        // Do nothing
    }

    @Override
    default void onTextChanged(CharSequence s, int start, int before, int count) {
        // Do nothing
    }

    @Override
    void afterTextChanged(Editable s);
}
Run Code Online (Sandbox Code Playgroud)

这是使用此接口的代码部分:

mSomeEditText.addTextChangedListener((AfterTextChangedListener) editable -> {
    // Logic using 'editable'.
});
Run Code Online (Sandbox Code Playgroud)

这是崩溃的 …

java android textwatcher java-8 default-method

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