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

关于使用MethodHandle在子类中调用祖父类重写方法的探究

关于使用MethodHandle在子类中调用祖父类重写方法的探究 注:这个例子原本出现在周志明先生的《深入理解Java虚拟机》--虚拟机字节码执行引擎章节,介于有读者朋友有疑问,这里基于Java代码层面解释一下...在普通的方法调用中,这个this参数是虚拟机自动处理的,表示的是当前实例对象,我们在方法中可以直接使用。...我觉得使用bindTo绑定方法接收者要比在invoke方法中传递更加友好,也更加符合程序员的大众理解,invoke可以只专注方法显式的入参。 然后再来说bindTo(this)中的this。...基于这个事实,我们这时可以直接在GrandFather的thinking方法中调用Son类独有的方法,使用反射或者直接类型强制转换为Son就行了。...这个参数中指定的是方法接收者的类型,bindTo指定的接收者的类型必须要是这个类或子类,不然会出现ClassCastException异常。

9.5K30
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    什么是java的多态

    多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3 所示。...要理解这是为什么,我们要先理解下面这句话: 当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法...(但是如果强制把超类转换成子类的话,就可以调用子类中新添加而超类没有的方法了) 看一下标红的那句话,我们知道问题所在了吗?...它说:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。...B里面的show(B obj)在超类A中有定义吗?没有!那就更谈不上被覆盖了。实际上这句话隐藏了一条信息:它仍然是按照方法调用的优先级来确定的。

    55920

    《Head First 设计模式》学习笔记 | 策略模式

    一开始,你可能会设计一个鸭子的超类 Duck,然后让所有不同种类的鸭子继承它: ? 设计一个鸭子超类(Superclass) 如果此时我们想让鸭子飞起来,就要在超类中增加一个 fly() 方法: ?...为了让它尊重客观事实,我们需要在小黄鸭类中覆盖超类的 quack() 和 fly() 方法,让它变得不会叫也不会飞。 ?...在小黄鸭中覆盖原有的方法 虽然我们用「覆盖方法」的手段解决了小黄鸭的问题,但未来我们可能还会制造更多奇奇怪怪的鸭子。...因此,我们可以在鸭子超类(Duck)中加入「行为类」的实例变量,从而通过这些实例变量来调用具体的行为方法。 ?...在 Class Duck 的 fly() 方法中,我们可以使用实例 flyBehavior 调用具体的行为方法,从而达成「委托」的目的: public function fly() { $this

    80100

    多态易错题

    如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写(Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。...当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。...它说:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。...但是为什么跟前面的分析得到的结果不相符呢?!问题在于我们不要忽略了蓝色字体的后半部分,那里特别指明:这个被调用的方法必须是在超类中定义过的,也就是被子类覆盖的方法。...B里面的show(B obj)在超类A中有定义吗?没有!那就更谈不上被覆盖了。实际上这句话隐藏了一条信息:它仍然是按照方法调用的优先级来确定的。

    62820

    PHP设计模式之策略模式 转

    介绍 策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。...我来解释下这个思维导图的过程: 1.Joe做了一套相当成功的模拟鸭子的游戏。设计了一个超类Duck,然后让各种鸭子继承这个类。 2.后来客户提出要让鸭子有飞的能力。...所以Joe就在超类中加了个fly()方法,这样下面的子类都有飞行的行为。    问题来了:1>原来Duck的子类中竟然有橡皮鸭,橡皮鸭是不会飞的。...问题来了:产品经常处于更新中,规格也在不断的变化。导致每当有新鸭子的时候,Joe就要被迫检查一遍子类是否覆盖了fly()方法。...——当你修改某个行为的时候,你必须得往下追踪并在每一个定义此行为的类中修改它。 4.综合以上问题,Joe想到了把那些变化的部分从不变化的位置中抽出来。

    40410

    14道Java开发岗面试题

    答: 使用final关键字修饰一个变量时,是指引用变量不能变, 引用变量所指向的对象中的内容还是可以改变的 3、"=="和equals方法究竟有什么区别?...答案( 1、””是运算符, 2、equals是超(人)类(型)Object中的方法 3、””比较基本类型是数值, 引用类型是地址比较内存地址, String类中重写的equals方法比较的是值..., 否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。...子类覆盖父类方法,方法访问权限必须大于等于父类 5.覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类; 表反派附议 overload要注意以下的几点: 1.重载只和参数列表有关...2.抽象类中可以有普通成员变量,接口中没有普通成员变量 3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。

    41710

    静态代码块、静态变量,构造代码块、实例变量的执行顺序和继承逻辑

    其实这就是Java的继承机制,对此说明如下: 属性属于实例自己的,所以Parent的age属性值是18,这就解释通了 属性不存在覆盖(即使同名),而方法是实实在在的覆盖(复写)。...但是,但是,但是,如果构造快为有参构造,请记得显示调用super方法,否则父类是不能被初始化的。如果子类的构造器没有显示地调用超类的构造器,则将自动调用超类默认(没有参数) 的构造器。...如果超类没有不带参数的构造器,并且在子类的构造器又没有显式地调用超类的其他构造器,则 java 编译器将报告错误~ 变种面试题 public class StaticTest { public...默认情况下,子类在使用构造函数初始化时(不管是子类使用有参构造还是无参构造),默认情况下都会调用父类的无参构造函数(相当于调用了super())。...2、super(id)必须显示的写出,否则编译不通过 3、原则上,子类的构造函数不能多于父类的 4、子类构造函数若多余父类(或者类型啥的和父类不匹配),需要显示的调用父类构造函数

    97650

    java父类引用指向子类对象好处_java子类调用父类属性

    子类覆盖父类实现多态: 如果子类继承的超类是一个抽象类,虽然抽象类不能通过new操作符实例化,但是可以创建抽象类的对象引用指向子类对象,以实现运行时多态性,不过,抽象类的子类必须覆盖实现超类中的所有的抽象方法...因为子类是对父类的一个改进和扩充,所以一般子类在功能上较父类更强大,属性较父类更独特: 定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。...所以,父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的; 对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接...而子类重写了func2()方法,那么父类类型的引用child在调用该方法时将会调用子类中重写的func2()。 经过上面的分析我们可以知道打印的结果是什么呢?...很显然,应该是”CCC” 4.对于多态总结一下 一、使用父类类型的引用指向子类的对象; 二、该引用只能调用父类中定义的方法和变量; 三、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候

    1.3K20

    JAVA 什么是多态?

    大家好,又见面了,我是你们的朋友全栈君。 面向对象编程有三大特性:封装、继承、多态。 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据。...对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法。 继承是为了重用父类代码。两个类若存在IS-A的关系就可以使用继承。,同时继承也为实现多态做了铺垫。 那么,什么是多态呢?...接口性(interface-ability):多 态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3 所示。...方法重写的应用: 当子类需要父类的功能,而功能主体子类有自己的特有内容时,可以重写父类中的方法。即沿用了父类的功能,又定义了子类特有的内容。...,即静态只能覆盖静态 子类重写父类方法时,最好声明得一模一样 如果子类中定义了一个与父类private方法具有相同的方法名、相同的形参列表、相同的返回值类型的方法,依然不是重写,只是在子类中重新定义了一个新的方法

    91330

    【小家java】类中静态代码块、构造代码块、静态变量、成员变量执行顺序和继承逻辑

    父类和子类的变量是同时存在的,即使是同名。子类中看到的是子类的变量,父类中看到的是父类中的变量,它们互相隐藏,而同名的方法则是实实在在的覆盖(重写),属性不存在重写哟。...但是,但是,但是,如果构造快为有参构造,请记得显示调用super方法,否则父类是不能被初始化的。如果子类的构造器没有显示地调用超类的构造器,则将自动调用超类默认(没有参数) 的构造器。...如果超类没有不带参数的构造器,并且在子类的构造器又没有显式地调用超类的其他构造器,则 java 编译器将报告错误 情况四:子类和父类有同名同类型的静态常量的时候 public class Main...因为false指明了装载类的过程中,不进行初始化。不初始化则不会执行static块。...至于spring中观察者模式的使用,我在后续文章中会重点分享,请持续关注 3、使用场景 各种设计模式,都会以此为依托,才能有更好的设计 子类默认调用父类构造函数问题 默认情况下,子类在使用构造函数初始化时

    1.5K20

    如何理解 Java 中接口存在的意义

    new Person("Jack"); // Error 可以定义一个抽象类的对象变量, 但是它只能引用非抽象子类的对象。...如果不这么做(可以选择不做),子类仍然是一个抽象类,编译器会强制我们为新类加上 abstract 关键字。...而 Java 8 中接口出现了些许的变化,开始允许接口包含默认方法和静态方法,这个下文会讲解。 Java 使用关键字 interface 而不是 class 来创建接口。...因此,一般更倾向使用接口而不是抽象类。 4. Java 8 接口新特性 上文提过一嘴,「在 Java 8 中,允许在接口中增加静态方法和默认方法」。...如果一个父类接口提供了一个默认方法,另一个父类接口也提供了一个同名而且参数类型相同的方法,子类必须覆盖这个方法来解决冲突。

    1.4K10

    Java面试-面向对象

    在Java中,运行时多态性或动态方法分派是一个在运行时而不是在编译时解决对覆盖方法的调用的过程。在此过程中,将通过超类的引用变量调用重写的方法。让我们看下面的示例,以更好地理解它。...在两种类型的类之间执行继承: 超级类(超级类或基础类) 子类(子类或派生类) 继承属性的类称为“子类”,而继承属性的类称为“父类”。 Q7。Java中继承有哪些不同类型?...您可以覆盖Java中的私有或静态方法吗? 您不能在Java中覆盖私有或静态方法。如果您在子类中创建具有相同返回类型和相同方法参数的类似方法,则它将隐藏超类方法;否则,它将隐藏超类方法。这称为方法隐藏。...同样,您不能覆盖子类中的私有方法,因为在那里无法访问它。您可以做的是在子类中创建另一个具有相同名称的私有方法。让我们看下面的示例,以更好地理解它。...Java支持吗? 如果子类从多个类继承属性,则称为多重继承。Java不允许扩展多个类。 多重继承的问题在于,如果多个父类具有相同的方法名称,则在运行时,编译器将很难从子类中决定执行哪个方法。

    71520

    Java核心技术 卷I 基础知识 学习笔记(4)

    将方法或类声明为final的主要目的是:确保它们不会再子类中改变语义。 如果一个方法没有被覆盖并且很短,编译器就能够对它进行优化处理,这个过程称为内联。...虚拟机中的即使编译器比传统编译器的处理能力强得多。这种编译器可以准确地知道类之间的继承关系,并能够检测出类中是否真正地存在覆盖给定的方法。...抽象方法充当着占位的角色,它们的具体实现在子类中。扩展抽象类可以有两种选择。...一种是在抽象类中定义部分抽象类方法或不定义抽象类方法,这样就必须将子类也标记为抽象类,另一种是定义全部的抽象方法,这样一来,子类就不是抽象的了。 类即使不包含抽象方法,也可以将类声明为抽象类。...抽象类不能被实例化。 需要注意的是,可以定义一个抽象类的对象变量,但是它只能引用非抽象子类的对象。 在子类中定义equals方法时,首先调用超类的equals。

    51740

    【Java提高三】三大特性-多态

    这样做存在一个非常大的好处,在继承中我们知道子类是父类的扩展,它可以提供比父类更加强大的功能,如果我们定义了一个指向子类的父类引用类型,那么它除了能够引用父类的共性外,还可以使用子类强大的功能。...所以对于多态我们可以总结如下: 指向子类的父类引用由于向上转型了,它只能访问父类中拥有的方法和属性,而对于子类中存在而父类中不存在的方法,该引用是不能使用的,尽管是重载该方法。...对于Java而言,它多态的实现机制遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法...首先我们先看一句话:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。...所以多态机制遵循的原则概括为:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法,但是它仍然要根据继承链中方法调用的优先级来确认方法

    68490

    Java 小白成长记 · 第 6 篇「为什么说要慎用继承,优先使用组合」

    上面这个方法输出的将是 I'm cat, I'm breathing,也就是说,在子类中可以使用 super 关键字调用父类的方法。...另外,一定要注意的是:「在覆盖一个方法的时候,子类方法不能低于父类方法的可见性」。特别是, 如果超类方法是 public, 子类方法一定要声明为 public。...例如,如果将父类 Animal中的 age声明为 proteced,而不是私有的, Cat中的方法就可以直接地访问它,「即使子类和父类不在一个包下」。...这表明子类得到信任,可以正确地使用这个方法,而不和父类在同一个包下的其他类则不行。 ? 7....Java 中的单继承 在深入学习 Java 之前,我学的其实是 C++,而 C++ 是支持多继承的,也就是说 A 可以同时继承 B 和 C 甚至更多。

    98820

    Head First设计模式——策略模式

    但是问题出现了,橡皮鸭是不会飞的,于是我们可以像覆盖qucak方法一样在RubberDuck中覆盖fly方法。...2、很难知道所有子类的行为。 3、运行的子类行为不容易改变。 4、改变会牵一发动全身,引起其他子类不想要的改变。 每当有新的子类出现,就要检查是不是需要覆盖父类方法。...这样鸭子类就不会负责实现FlyBehavior与QuackBehavior,而是由行为类来专门实现,不会绑死在鸭子的子类中。 ? 而"针对接口编程"的意思是"针对超类型编程"。...可以明确地说明变量的声明类型应该是超类,这意味着我们在Duck父类中声明的行为变量为 FlyBehavior,QuackBehavior,"针对接口编程"的关键就在于面向对象三要素之一的"多态",由于多态我们才能在调用超类的方法时执行的是实现类或子类的方法...如上测试我们在鸭子子类中通过构造方法实例化行为类,但建立了一堆动态的功能没有用到,是否可以动态的设定行为而不是在构造函数里面实例化。

    36921

    Java异常面试问题

    throws:当我们在方法中抛出任何已检查的异常而不处理它时,我们需要在方法签名中使用throws关键字让调用者程序知道该方法可能抛出的异常。...String getLocalizedMessage() - 提供此方法,以便子类可以覆盖它以向调用程序提供特定于语言环境的消息。...未经检查的异常主要是由编程不良引起的,例如在对象引用上调用方法时的NullPointerException,而不确保它不为null。例如,我可以编写一个方法来从字符串中删除所有元音。...我们可以扩展Exception类或其任何子类来创建我们的自定义异常类。自定义异常类可以拥有自己的变量和方法,我们可以使用它们将错误代码或其他与异常相关的信息传递给异常处理程序。...final和finally是java中的关键字,而finalize是一种方法。 final关键字可以与类变量一起使用,以便它们不能被重新分配,类可以避免按类扩展,并且使用方法来避免子类覆盖。

    1K30

    Java面试集锦(一)之Java异常

    throws:当我们在方法中抛出任何已检查的异常而不处理它时,我们需要在方法签名中使用throws关键字让调用者程序知道该方法可能抛出的异常。...String getLocalizedMessage() - 提供此方法,以便子类可以覆盖它以向调用程序提供特定于语言环境的消息。...未经检查的异常不需要在程序中处理或在方法的throws子句中提及它们。 Exception是所有已检查异常RuntimeException的超类,而是所有未经检查的异常的超类。...未经检查的异常主要是由编程不良引起的,例如在对象引用上调用方法时的NullPointerException,而不确保它不为null。例如,我可以编写一个方法来从字符串中删除所有元音。...确保不传递空字符串是调用者的责任。我可能会改变方法来处理这些场景,但理想情况下,调用者应该处理这个问题。 6.

    1K40
    领券