我有一个基类,比如 named B
。我有两个派生类,D1
和D2
.
好像:
public abstract class B
{
public abstract void DoSomething();
}
public class D1 : B
{
public override void DoSomething() { ... }
}
public class D2 : B
{
public override void DoSomething() { ... }
}
Run Code Online (Sandbox Code Playgroud)
现在,我创建了一个新界面IDeepCopyable<T>
,它有一个方法Clone()
:
public interface IDeepCopyable<T>
{
T Clone();
}
Run Code Online (Sandbox Code Playgroud)
我想强制每个子类也使用基类(即IDeepCopyable<B>
.
如果我尝试将B
's 声明保持原样,但只是继承自 ('implement' 是一个更准确的术语?) IDeepCopyable<T>
,例如:
public abstract class B : IDeepCopyable<B>
Run Code Online (Sandbox Code Playgroud)
然后在派生类中实现它(隐式或显式),编译器给我一条错误消息“B …
简而言之,在 Java 的 LTS 版本 (Java 17) 中,我们第一次有了关键字sealed
,它使我们能够限制层次结构:
public abstract sealed class Person
permits Employee, Manager {
//...
}
Run Code Online (Sandbox Code Playgroud)
如果我想创建一个扩展基类的新子类Person
,我也必须修改基类。这是否违反开闭原则?
今天遇到了这个问题,花了很多年时间试图重现/弄清楚发生了什么.有人可以解释为什么会发生这种情况,或者这是类型擦除/默认方法/ lambda/polymorphism的错误?取消注释默认方法可以使它运行正常,但我希望它能够按原样运行
输出:
Works fine with an object
Calling consume
Hello
Calling accept with context
Hello
Calling accept via consumer...
Exception in thread "main" java.lang.AbstractMethodError: Method test/LambdaTest$$Lambda$1.accept(Ljava/lang/Object;)V is abstract
at test.LambdaTest$$Lambda$1/834600351.accept(Unknown Source)
at test.LambdaTest.main(LambdaTest.java:24)
Run Code Online (Sandbox Code Playgroud)
码
package test;
import java.util.function.Consumer;
public class LambdaTest {
public static void main(String[] args) {
Consumer<Context> contextIgnoringObject = new ContextUnawareObject();
contextIgnoringObject.accept(new Context());
ContextIgnorer contextIgnoringLambda = () -> {
System.err.println("Hello");
};
System.err.println("Calling consume");
contextIgnoringLambda.consume();
System.err.println("Calling accept with context");
contextIgnoringLambda.accept(new Context());
Consumer<Context> consumer = contextIgnoringLambda;
System.err.println("Calling accept via …
Run Code Online (Sandbox Code Playgroud) 我想知道是否有任何方法可以在阵列上的单次迭代中实现以下内容.只需要有两个不同的结果流出.
double sum = Arrays.stream(doubles).sum();
double sumOfSquares = Arrays.stream(doubles).map(d -> d * d).sum();
Run Code Online (Sandbox Code Playgroud) 当Java 21引入有序集合时,我非常高兴开始使用它们。但后来我很快发现JDK的各个角落似乎都会自然地应用新的排序接口,但它们并没有应用。我找不到对此的任何确认,也找不到任何证据表明未来有计划进一步将排序集合接口的使用扩展到更多 JDK 中。这让我感到惊讶,因为 JDK 的作者通常倾向于保持事物的一致性和完整性。
一个具体的例子是EnumSet
。据我所知,没有根本原因EnumSet
不能/不应该实施SequencedSet
. 难道只是没有人愿意付出努力来实现一种reversed()
方法吗EnumSet
?或者有什么更严重的问题阻止了它?
我想创建一个函数来获取Class的参数并返回T的实例,
所以我有这个签名:
public <T> T foo(Class<T> clazz) {}
Run Code Online (Sandbox Code Playgroud)
现在,假设我想限制Class<T>
并仅接受<T extends Command>
,所以我尝试了这个:
public <T> T foo(Class<T extends Command> clazz) {}
Run Code Online (Sandbox Code Playgroud)
但是,我的班级Command
也是模板如下:Command<S extends ModuleContex>
所以我试试这个:
public <T> T foo(Class<T extends Command<S extends ModuleContext>> clazz) {}
Run Code Online (Sandbox Code Playgroud)
但这不编译!
如何正确写?
java ×4
java-8 ×3
c# ×1
collections ×1
enumset ×1
java-17 ×1
java-21 ×1
java-stream ×1
lambda ×1
sealed-class ×1
sequencedset ×1
type-erasure ×1