首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Java当T扩展接口时,为什么T仍然调用默认方法

当Java中的接口T扩展时,T仍然调用默认方法的原因是为了保持向后兼容性和代码的一致性。

在Java 8之前,接口只能定义抽象方法,而不能包含具体的实现。这导致了一个问题,即当一个接口需要添加新的方法时,所有实现该接口的类都必须实现这个新方法,否则会导致编译错误。

为了解决这个问题,Java 8引入了默认方法(default methods)的概念。默认方法是接口中带有实现的方法,它们可以在接口中直接定义,而不需要实现类去实现它们。这样一来,当一个接口需要添加新的方法时,实现该接口的类可以选择性地覆盖默认方法,或者继续使用默认方法的实现。

当接口T扩展时,如果T继承了一个接口A,并且A中定义了一个默认方法,那么T会继承该默认方法。这意味着,当T调用该默认方法时,会执行A中定义的默认实现。

这种设计决策的目的是为了保持向后兼容性。如果T在扩展时不继承默认方法,那么所有已经实现了接口A的类都必须修改代码来实现新的方法,这将导致大量的代码改动和可能的错误。通过继承默认方法,已经实现了接口A的类可以继续使用默认方法的实现,而不需要做任何修改。

此外,继承默认方法还可以提供更灵活的代码复用和组合。通过继承多个接口,一个类可以获得多个默认方法的实现,从而实现更丰富的功能。

总结起来,当Java中的接口T扩展时,T仍然调用默认方法是为了保持向后兼容性、代码的一致性和灵活的代码复用。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

从 Kotlin 开发者角度看 Java 缺失的特性

虽然 Kotlin 也被编译为 JVM 字节码,但有时候我还是不得不写一些  Java 代码。每次写 Java 代码,我都不禁想,为什么 Java 代码看起来没有 Kotlin 那么好。...Java 允许你定义不可变引用,但不是强制的。默认情况下,引用是可变的。大多数 Java 代码没有使用不可变引用。...Kotlin 提供了不通过类继承或使用装饰器等设计模式来实现扩展类或接口的能力。这可以通过一种叫作扩展的特殊声明来实现。  例如,你可以为你无法修改的第三方库中的类或接口添加新函数。...这些函数可以按照通常的方式进行调用,就好像它们就是原始类的方法一样。这种机制叫作扩展函数。  要声明扩展函数,需要用被扩展的类名作为前缀。...Kotlin 仍然需要遵循 JVM 规范,并与 Java 编译器生成的字节码兼容。它可以通过内联来实现:编译器用函数体替换内联的方法调用

78920
  • Java8 默认方法 default method

    为什么要有默认方法java 8 之前,接口与其实现类之间的 耦合度 太高了(tightly coupled),需要为一个接口添加方法,所有的实现类都必须随之修改。... ClassB 类覆写 foo 方法,无法通过 InterfaceA.super.foo(); 调用 InterfaceA 接口的 foo 方法。...接口与抽象类 接口继承行为发生冲突的另一个规则是,类的方法声明优先于接口默认方法,无论该方法是具体的还是抽象的。...虽然 Java 8 的接口默认方法就像抽象类,能提供方法的实现,但是他们俩仍然是 不可相互代替的: 接口可以被类多实现(被其他接口多继承),抽象类只能被单继承。...即使使用了 java 8 的环境,一些 IDE 仍然可能在一些代码的实时编译提示出现异常的提示(例如无法发现 java 8 的语法错误),因此不要过度依赖 IDE。

    1K41

    Java线程面试题 Top 50

    java.lang.Thread 类的实例就是一个线程但是它需要调用java.lang.Runnable接口来执行,由于线程类本身就是调用的Runnable接口所以你可以继承java.lang.Thread...这个问题很容易回答,如果你知道Java不支持类的多重继承,但允许你调用多个接口。所以如果你要继承其他类,当然是调用Runnable接口好了。...因此,一个等待线程醒来时,不能认为它原来的等待状态仍然是有效的,在notify()方法调用之后和等待线程醒来之前这段时间它可能会改变。...比如你不能扩展锁之外的方法或者块边界,尝试获取锁不能中途取消等。Java 5 通过Lock接口提供了更复杂的控制来解决这些问题。...为了确保三个线程的顺序你应该先启动最后一个(T3调用T2,T2调用T1),这样T1就会先完成而T3最后完成。 34) Thread类中的yield方法有什么作用?

    1.1K20

    java多线程面试题大全_java多线程面试题_线程并发面试题

    两种方式:java.lang.Thread 类的实例就是一个线程但是它需要调用java.lang.Runnable接口来执行,由于线程类本身就是调用的Runnable接口所以你可以继承java.lang.Thread...类或者直接调用Runnable接口来重写run()方法实现线程。...synchronized 它用来修饰一个方法或者一个代码块的时候,能够保证在同一刻最多只有一个线程执行该段代码。...二、然而,一个线程访问object的一个synchronized(this)同步代码块,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。...当我们在Java程序中新建一个线程,它的状态是New。当我们调用线程的start()方法,状态被改变为Runnable。

    39630

    Java 中文官方教程 2022 版(四)

    要使用接口,您需要编写一个实现接口的类。一个可实例化的类实现一个接口,它为接口中声明的每个方法提供一个方法体。...然而,一个类只能扩展一个其他类,而一个接口可以扩展任意数量的接口接口声明包括一个逗号分隔的所有它扩展接口的列表。 接口主体 接口主体可以包含抽象方法默认方法,和静态方法。...扩展包含默认方法接口,可以执行以下操作: 完全不提及默认方法,让您扩展接口继承默认方法。...接口方法 默认方法和抽象方法接口中像实例方法一样被继承。然而,一个类或接口的超类型提供了多个具有相同签名的默认方法Java 编译器遵循继承规则来解决名称冲突。...这种形式的方法调用不仅限于区分包含具有相同签名的默认方法的多个实现接口。您可以使用super关键字在类和接口调用默认方法。 从类中继承的实例方法可以覆盖抽象接口方法

    18700

    被问到的JDK8新特性

    Java从已经从JDK1.0版本发展到了最新的JDK13, 为什么目前Jdk8经常被问到呢? 大概有一些原因: 第一、JDK8仍然是最受欢迎的JDK版本。...默认方法和静态方法 JDK1.8支持在接口中定义默认方法和静态方法默认方法可以被接口实现引用。...改动有两个方面: 支持了lambda, 流和聚合操作 改进的类型推断 改进的类型推断 Java编译器利用目标类型来推断通用方法调用的类型参数。...Java SE 7和更早版本的编译器不接受此代码,因为它们不使用目标类型来推断方法调用参数的类型。...链表长度小于6,红黑树的方式退化成链表。 JDK7链表插入是从链表头部插入, 在resize的时候会将原来的链表逆序。 JDK8插入从链表尾部插入, 因此在resize的时候仍然保持原来的顺序。

    35940

    如何扩展和优化线程池?

    有一个新的任务提交,线程池中若有空闲线程,则立即执行,若没有,则新的任务会被暂存在一个任务队列(默认无界队列 int 最大数)中,待有线程空闲时,便处理在任务队列中的任务。 2....如何手动创建线程池 下面是一个手动创建线程池的范本: /** * 默认5条线程(默认数量,即最少数量), * 最大20线程(指定了线程池中的最大线程数量), * 空闲时间0秒(线程池梳理超过核心数量...队列满了,如何处理那些仍然提交的任务。JDK 默认有4种策略。 AbortPolicy :直接抛出异常,阻止系统正常工作....如何扩展线程池 那么我们能扩展线程池的功能吗?比如记录线程任务的执行时间。实际上,JDK 的线程池已经为我们预留的接口,在线程池核心方法中,有2 个方法是空的,就是给我们预留的。...还有一个线程池退出时会调用方法。我们看看例子: /** * 如何扩展线程池,重写 beforeExecute, afterExecute, terminated 方法,这三个方法默认是空的。

    1.2K20

    《Kotin 极简教程》第8章 函数式编程(FP)(2)

    为了让事情简单化(在Java 8中,增加Lambda表达式的支持),我们在Kotlin中使用普通的函数来替代函数式接口。事实上,函数式编程中的函数,比C语言中的函数或者Java中的方法都要强大的多。...函数参数可以有默认值,省略相应的参数使用默认值。...覆盖一个带有默认参数值的方法,签名中不带默认参数值: open class DefaultParamBase { open fun add(x: Int = 0, y: Int = 0):...一个函数有大量的参数或默认参数这会非常方便。...reformat(str) 然而,使用非默认参数调用,该调用看起来就像 reformat(str, true, true, false, '_') 使用命名参数我们可以使代码更具有可读性 reformat

    1.8K20

    如何在项目中引入SPI

    Java SPI Java SPI 中有四个重要的组件: 服务接口:一个定义了服务提供者实现类契约方法接口或者抽象类。 服务实现:实际提供服务的实现类。...表明该接口默认实现是别名为 fixed 的实现类,即 FixedThreadPool 。...ExtensionLoader 对象,会判断是否是 interface ,也会通过 withExtensionAnnotation 方法判断该接口是否有 @SPI 注解,没有的话会抛出异常,表明该接口不是一个可以扩展接口...实例就可以调用 getExtension 方法指定实现类的别名,来获取该实现类的实例。...如果 cachedInstances 中获取不到 Holder 对象,就会调用 createExtension 方法获取接口的具体实现类对象,放入承载对象中,然后就可以返回实现类的实例。

    50460

    Dubbo系列讲解之扩展点实现原理分析【2万字分享】

    在需要使用扩展点的地方调用java.util.ServiceLoader#load(java.lang.Class)方法,传入接口的全类名,返回java.util.ServiceLoader,ServiceLoader...标注在类上,表示该扩展类是默认的自适应扩展点,标注在方法,表示该方法是自适应扩展点,将会重写该方法,使得Dubbo能够在运行时获取到具体的扩展点。...然后我们回到   再次回到getAdaptiveExtensionClass()方法执行完getExtensionClasses();方法之后,如果cacheAdaptiveClass为null,表示该扩展点没有默认的自适应扩展点...会将默认扩展点的name赋值到cachedDefaultName中,所以调用getDefaultExtension()即可获得默认扩展点实现 if ("true".equals(name...然后调用initExtension方法,如果该对象实现了Lifecycle接口,则调用initialize方法

    38630

    如何扩展和优化线程池?

    有一个新的任务提交,线程池中若有空闲线程,则立即执行,若没有,则新的任务会被暂存在一个任务队列(默认无界队列 int 最大数)中,待有线程空闲时,便处理在任务队列中的任务。...队列满了,如何处理那些仍然提交的任务。JDK 默认有4种策略。 AbortPolicy :直接抛出异常,阻止系统正常工作....优先级为默认。 如果我们想修改名称呢?对,实现 ThreadFactory 接口,重写 newThread 方法即可。...三、如何扩展线程池 ---- 那么我们能扩展线程池的功能吗?比如记录线程任务的执行时间。实际上,JDK 的线程池已经为我们预留的接口,在线程池核心方法中,有2 个方法是空的,就是给我们预留的。...还有一个线程池退出时会调用方法。我们看看例子: /** * 如何扩展线程池,重写 beforeExecute, afterExecute, terminated 方法,这三个方法默认是空的。

    76600

    深入理解 Java 线程池

    提高响应速度 - 任务到达,任务可以不需要等到线程创建就能立即执行。..., ExecutionException, TimeoutException; } 从其支持的方法定义,不难看出:相比于 Executor 接口,ExecutorService 接口主要的扩展是: 支持有返回值的线程...在线程池处于 RUNNING 状态调用 shutdown 方法会使线程池进入到该状态。 finalize 方法在执行过程中也会调用 shutdown 方法进入该状态。 STOP - 停止状态。...在线程池处于 RUNNING 或 SHUTDOWN 状态调用 shutdownNow 方法会使线程池进入到该状态。 TIDYING - 整理状态。...有新任务通过 execute 方法提交 ,线程池会执行以下判断: 如果运行的线程数少于 corePoolSize,则创建新线程来处理任务,即使线程池中的其他线程是空闲的。

    48930

    高频多线程&并发面试题(附答案,纯干货)(一)

    12、为什么wait, notify 和 notifyAll这些方法不在thread类里面? 明显的原因是JAVA提供的锁是对象级的而不是线程级的,每个对象都有锁,通过线程获得。...13、为什么wait和notify方法要在同步块中调用? 1.只有在调用线程拥有某个对象的独占锁,才能够调用该对象的wait(),notify()和notifyAll()方法。...为了确保三个线程的顺序你应该先启动最后一个(T3调用T2,T2调用T1),这样T1就会先完成而T3最后完成。...所以,只要有一个线程访问map,其他线程就无法进入map,而如果一个线程在访问ConcurrentHashMap某个桶,其他线程,仍然可以对map执行某些操作。...接口中,它扩展了Executor接口,其它线程池类像ThreadPoolExecutor和ScheduledThreadPoolExecutor都有这些方法

    95220

    Kotlin —— 这次入门就不用放弃了

    } //注:此处的toast方法是Kotlin默认已经提供的扩展方法 5. 互操作性 Kotlin调用JavaJava调用Kotlin与之前的Java 类之间调用方式没有太大差别,不详细介绍。...所以使用Gson.fromJson(String json , Class classOf)方法,虽然传入了类型参数,实际上这个T仍然是个Object。...T> classOf)`方法 return fromJson(json, T::class.java) } 这里需要指定T类型为Any,即Object类。...并且Button中有一个点击事件,点击将EditText的内容以toast显示。 ? 在上面创建UI过程中,我们直接把创建UI的代码写在onCreate方法中了,当然,还有一种写法。...它是说,每次我追加一个字符串到一些东西(一个 StringBuilder、某种日志、一个控制台等)上我就必须捕获那些 IOException。 为什么

    1.7K30

    Java】函数式接口

    需要 注 意 的是,即使不使用该注解,只要满足函数式接口的定义,这仍然是一个函数式接口,使用起来都 一样。...扩展:实际上使用内部类也可以达到同样的效果,只是将代码操作延迟到了另外一个对象当中通过 调用方法 来完成。而是否调用其所在方法是在条件判断之后才执行的。...需要通过一 个方法来获取一个 java.util.Comparator 接口类型的对象作为排序器 , 就可以调该方法获取。 其中直接return一个Lambda表达式即可。...下面是最简单的几个接口及使用示例。 3.1 Supplier接口 java.util.function.Supplier 接口仅包含一个无参的方法T get() 。...当然,最好是通过方法引用的写法。 默认方法: andThen Function 接口中有一个默认的 andThen 方法,用来进行组合操作。

    63840

    JDK8新特性总结

    @FunctionalInterface) 函数式接口指的是有且只有一个抽象(abstract)方法接口 需要一个函数式接口的对象,就可以用Lambda表达式来实现,举个常用的例子: Thread...JDK8接口规范 在JDK8中引入了lambda表达式,出现了函数式接口的概念,为了在扩展接口保持向前兼容性(JDK8之前扩展接口会使得实现了该接口的类必须实现添加的方法,否则会报错。...从以上改变不难看出,修改接口的规范主要是为了能在扩展接口保持向前兼容。...DefaultMethod.defaultMethod(); } } 可以看到default方法确实像实例方法一样,必须有实例对象才能调用,并且子类在实现接口,可以不用实现default方法,...大家其实不必细究类型推断,在日常使用中IDE会自动判断,IDE自己无法推断出足够的信息,就需要我们额外做一下工作,比如在里添加更多的类型信息, 相信随着Java的进化,这些便利的功能会越来越强大

    1.2K50

    Spring Data JPA 参考文档二

    在 package-info.java @org.springframework.lang.NonNullApi package com.acme; 一旦非空默认设置到位,存储库查询方法调用将在运行时验证为可空性约束...方法将返回null但被声明为不可为空(在存储库所在的包上定义的默认注释),就会发生这种情况。如果您想再次选择可空结果,请有选择地使用@Nullable单个方法。...EmptyResultDataAccessException查询未产生结果抛出。IllegalArgumentExceptionemailAddress传递给方法抛出null。...} 该方法将参数和结果都定义为不可为空(Kotlin 默认值)。Kotlin 编译器拒绝传递null给方法方法调用。...使用过滤器 默认情况下,基础设施会选择每个接口,这些接口扩展Repository位于配置的基本包下的持久性技术特定的子接口,并为其创建一个 bean 实例。

    1.1K30
    领券