我已经default在接口中创建了用于实现equals(Object)和hashCode()以可预测方式的方法.我使用反射来迭代类型(类)中的所有字段以提取值并进行比较.代码依赖于Apache Commons Lang及其HashCodeBuilder和EqualsBuilder.
问题是我的测试告诉我,第一次调用这些方法时,第一次调用需要花费更多的时间.计时器使用System.nanoTime().以下是日志中的示例:
Time spent hashCode: 192444
Time spent hashCode: 45453
Time spent hashCode: 48386
Time spent hashCode: 50951
Run Code Online (Sandbox Code Playgroud)
实际代码:
public interface HashAndEquals {
default <T> int getHashCode(final T type) {
final List<Field> fields = Arrays.asList(type.getClass().getDeclaredFields());
final HashCodeBuilder builder = new HashCodeBuilder(31, 7);
fields.forEach( f -> {
try {
f.setAccessible(true);
builder.append(f.get(type));
} catch (IllegalAccessException e) {
throw new GenericException(e.toString(), 500);
}
});
return builder.toHashCode();
}
default <T, …Run Code Online (Sandbox Code Playgroud) 这是我在Java Tutorial中的简单代码.
public interface AnimalIntf {
default public String identifyMyself(){
return "I am an animal.";
}
}
Run Code Online (Sandbox Code Playgroud)
我得到一个错误:非法启动类型接口方法不能有body.该方法是default,默认关键字在方法签名的开头使用.你能告诉我有什么问题吗?
假设我们在接口中有一个默认方法,在实现类时如果我们需要添加一些额外的逻辑,除了我们必须复制整个方法的默认方法之外?是否有可能重用默认方法...就像我们使用抽象类一样
super.method()
// then our stuff...
Run Code Online (Sandbox Code Playgroud) Java有计划default method替代 Abstract Class吗?我找不到使用默认方法而不是抽象的真实案例?
我有一个带有默认方法的接口:
public interface Book {
String getTitle();
default String getSentenceForTitle() {
return "This book's title is " + getTitle();
}
}
Run Code Online (Sandbox Code Playgroud)
...我有一个@Entity实现这个接口的JPA :
@Entity
public class JpaBook implements Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String title;
// ...
@Override
public String getTitle() {
return title;
}
}
Run Code Online (Sandbox Code Playgroud)
使用这个实体,我注意到 Jackson 也会序列化默认方法getSentenceForTitle()- 尽管在我的特殊情况下,我不想sentenceForTitle被序列化。
有没有办法让杰克逊知道我不想序列化默认方法,但要保留该方法的行为?我想出的当前解决方法是覆盖默认方法,用 注释它@JsonIgnore,然后委托给默认方法:
@Entity
public class JpaBook implements Book {
// ...
@Override
@JsonIgnore
public String getSentenceForTitle() { …Run Code Online (Sandbox Code Playgroud) 我有一个class(Say FOO),它有一个具有default可见性的方法,如下所示:
void sayHi() {}
Run Code Online (Sandbox Code Playgroud)
现在,如果在扩展类I时覆盖此方法无法降低其可见性.所以我只能使用default或public.
public class MyClassTest extends FOO {
@Override
// Or I can use public void sayHi()
void sayHi() {
System.out.println("Overriden sayHi");
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我使用下面的默认方法在Java 8中编写接口:
public interface InterfaceX {
// Java-8 defalu method
default String printName() {
System.out.println("Interface1 default metod");
return "Interface1 default metod";
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我在类中重写此方法它应该编译,如果保持重写方法的可见性default.
public class Java8InterfaceTest implements InterfaceX{
@Override
void printHello() {
System.out.println("Printing..!");
Interface1.super.printName();
}
}
Run Code Online (Sandbox Code Playgroud)
它说
无法从InterfaceX降低继承方法的可见性
我已经知道,在每一个方法interface …
我从这里阅读有关java 8默认方法时遇到了以下段落:
如果层次结构中的任何类具有具有相同签名的方法,则默认方法变得无关紧要.默认方法不能覆盖java.lang.Object中的方法.原因很简单,因为Object是所有java类的基类.因此,即使我们将Object类方法定义为接口中的默认方法,它也将是无用的,因为将始终使用Object类方法.这就是为什么要避免混淆,我们不能有重写Object类方法的默认方法.
我很快尝试使用代码来确认行为
public class DefaultMethodClass {
public void defaultMethod()
{
System.out.println("DefaultMethodClass.defaultMethod()");
}
}
public interface DefaultMethodInterface {
public default void defaultMethod()
{
System.out.println("DefaultMethodInterface.defaultMethod()");
}
}
public class DefaultMethodClassInterfaceChild extends DefaultMethodClass implements DefaultMethodInterface
{
public static void main(String[] args) {
(new DefaultMethodClassInterfaceChild()).defaultMethod();
}
}
Run Code Online (Sandbox Code Playgroud)
这打印
DefaultMethodClass.defaultMethod()
Run Code Online (Sandbox Code Playgroud)
我无法看到为什么语言设计师选择这种特定行为背后的任何具体原因.他们的任何重要原因是我失踪了吗?或者它只是接口默认方法在逻辑上比超类提供的具体实现重要性低?
我在 Java 中有一个类 A,在 Kotlin 中有一个接口 B。
// kotlin
interface B {
fun optional()
}
Run Code Online (Sandbox Code Playgroud)
// java
class A implements B {
}
Run Code Online (Sandbox Code Playgroud)
我想在 Kotlin 接口 (B) 中编写默认方法(Java 8 特性),并想在类 A 中实现它,我该如何实现?
提前致谢。
我最近升级到java,我正在尝试接口的新默认方法.但是我不断在令牌"default"上获得语法错误,删除此令牌.这是我的构建路径,我预计会出现问题:
![在这里输入图像描述]![[1]](https://i.stack.imgur.com/FjEiJ.png)
我怀疑它与我的构建路径有关,但不知道是什么.如果它与我的代码有关,这里是我正在尝试的代码:
interface Test{
default void sayHelloWorld() {
System.out.println("Hello World");
}
}
Run Code Online (Sandbox Code Playgroud)
有人有任何想法吗?
我想为默认函数实现一个相等和比较功能的接口。
如果我从成员中删除IKeyable<'A>除Key成员之外的所有内容,则它是有效接口,只要不添加默认实现即可。从中删除其他接口实现IKeyable<'A>,并仅保留默认成员将以相同的结果结束。
type IKeyable<'A when 'A: equality and 'A :> IComparable> =
abstract member Key : 'A
default this.Equals obj = // hidden for clarity
default this.GetHashCode () = // hidden for clarity
interface IEquatable<'A> with
member this.Equals otherKey = // hidden for clarity
interface IComparable<'A> with
member this.CompareTo otherKey = // hidden for clarity
interface IComparable with
member this.CompareTo obj = // hidden for clarity
type Operation =
{ Id: Guid }
interface …Run Code Online (Sandbox Code Playgroud) 我正在尝试将日志记录添加到我的界面默认方法中。例如:
@Slf4j // not allowed
interface MyIFace {
default ThickAndThin doThisAndThat() {
log.error("default doThisAndThat() called");
}
}
Run Code Online (Sandbox Code Playgroud)
问题是我得到:
@Slf4j 仅在类和枚举上合法。
处理这个问题的正确方法是什么?
我浏览了许多帖子,但似乎都回答了接口的静态方法存储在哪里。但是,接口可以具有抽象、静态和默认方法。我知道静态和抽象方法。但是,我无法在内存中找到与默认方法存储相关的任何内容。
我可能错了,但我认为默认方法将存储在静态堆空间中,就像实例方法与类一起存储一样。但是,除此之外,考虑到实现类不会覆盖接口中默认方法的实现并且没有菱形问题,如果默认方法也被分配给堆栈帧,我也很困惑。
我参考了以下链接:
您经常听说接口中的方法没有实现。然而,在 Java 8 中,可以实现默认方法。但我很感兴趣。是否可以本地实现接口方法?(native方法)。
当面试问题被问到“是否可以在接口中实现方法?” 答案 - 您可以实现本机方法,并且从 Java 8 开始可以定义默认方法。” 这个答案正确吗?