为什么java输出写成b冒号加b_::(双冒号)运算符在Java 8中

由于许多答案在这里解释well :: behavior,另外我想澄清一下:: 运算符如果用于实例variables,不需要与引用的Functional Interface具有完全相同的签名 。 让我们假设我们需要一个具有TestObjecttypes的BinaryOperator 。 传统的方式是这样实现的:

BinaryOperator binary = new BinaryOperator() { @Override public TestObject apply(TestObject t, TestObject u) { return t; } };

正如您在匿名实现中看到的那样,它需要两个TestObject参数,并返回一个TestObject对象。 为了通过使用::运算符来满足这个条件,我们可以从一个静态方法开始:

public class TestObject { public static final TestObject testStatic(TestObject t, TestObject t2){ return t; } }

然后打电话给:

BinaryOperator binary = TestObject::testStatic;

好吧,它编译好。 如果我们需要实例方法呢? 让实例方法更新TestObject:

public class TestObject { public final TestObject testInstance(TestObject t, TestObject t2){ return t; } public static final TestObject testStatic(TestObject t, TestObject t2){ return t; } }

现在我们可以访问如下的实例:

TestObject testObject = new TestObject(); BinaryOperator binary = testObject::testInstance;

这段代码编译得很好,但是下面的代码不是:

BinaryOperator binary = TestObject::testInstance;

我的eclipse告诉我: “不能从typesTestObject的非静态方法testInstance(TestObject,TestObject)静态引用…”

公平的一个实例方法,但如果我们重载testInstance如下:

public class TestObject { public final TestObject testInstance(TestObject t){ return t; } public final TestObject testInstance(TestObject t, TestObject t2){ return t; } public static final TestObject testStatic(TestObject t, TestObject t2){ return t; } }

并致电:

BinaryOperator binary = TestObject::testInstance;

该代码将只是编译好。 因为它将使用单个参数而不是双testInstance调用testInstance 。 好吧,我们的两个参数发生了什么? 让打印输出,看看:

public class TestObject { public TestObject() { System.out.println(this.hashCode()); } public final TestObject testInstance(TestObject t){ System.out.println("Test instance called. this.hashCode:" + this.hashCode()); System.out.println("Given parameter hashCode:" + t.hashCode()); return t; } public final TestObject testInstance(TestObject t, TestObject t2){ return t; } public static final TestObject testStatic(TestObject t, TestObject t2){ return t; } }

哪个会输出:

1418481495 303563356 Test instance called. this.hashCode:1418481495 Given parameter hashCode:303563356

好,所以JVM足够聪明,可以调用param1.testInstance(param2)。 我们可以使用testInstance从另一个资源,但不是TestObject,即:

public class TestUtil { public final TestObject testInstance(TestObject t){ return t; } }

并致电:

BinaryOperator binary = TestUtil::testInstance;

它只是不编译,编译器会告诉: “typesTestUtil没有定义testInstance(TestObject,TestObject)” 。 所以编译器会寻找一个静态引用,如果它不是相同的types。 好的多态性呢? 如果我们删除最终修饰符并添加我们的SubTestObject类:

public class SubTestObject extends TestObject { public final TestObject testInstance(TestObject t){ return t; } }

并致电:

BinaryOperator binary = SubTestObject::testInstance;

它不会编译,编译器仍然会查找静态引用。 但是,下面的代码将通过testing:

public class TestObject { public SubTestObject testInstance(Object t){ return (SubTestObject) t; } } BinaryOperator binary = TestObject::testInstance;

*我只是在学习,所以我试着去了解,如果我错了,请随时纠正我

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值