考虑以下一组表达式:
class T {{
/*1*/ super.toString(); // direct
/*2*/ T.super.toString(); // synthetic
Supplier<?> s;
/*3*/ s = super::toString; // synthetic
/*4*/ s = T.super::toString; // synthetic
}}
Run Code Online (Sandbox Code Playgroud)
这给出了以下结果:
class T {
T();
0 aload_0 [this]
1 invokespecial java.lang.Object() [8]
4 aload_0 [this]
5 invokespecial java.lang.Object.toString() : java.lang.String [10]
8 pop // ^-- direct
9 aload_0 [this]
10 invokestatic T.access$0(T) : java.lang.String [14]
13 pop // ^-- synthetic
14 aload_0 [this]
15 invokedynamic 0 get(T) : java.util.function.Supplier [21]
20 astore_1 [s] …Run Code Online (Sandbox Code Playgroud) public class Car {
private int maxSpeed;
public Car(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
public int getMaxSpeed() {
return maxSpeed;
}
}
Run Code Online (Sandbox Code Playgroud)
我们可以按以下方式对汽车列表进行排序
Car carX = new Car(155);
Car carY = new Car(140);
List<Car> cars = new ArrayList<>();
cars.add(carX);
cars.add(carY);
cars.sort(Comparator.comparing(Car::getMaxSpeed));
Run Code Online (Sandbox Code Playgroud)
如果我们看到方法的签名Comparator.comparing,则输入参数类型为Function<? super T, ? extends U>
在上面的例子中,是如何Car::getMaxSpeed被转换为Function<? super T, ? extends U>而以下不编译?
Run Code Online (Sandbox Code Playgroud)Function<Void, Integer> function = Car::getMaxSpeed;
为什么以下代码无法编译.
Consumer con = (s) -> System.out::println;
它说
此表达式的目标类型必须是功能接口
即使消费者是功能界面.以下工作正常.
Consumer con2 = (s) -> {System.out.println(s);};
我有几个实现相同方法的预定义静态"处理器",例如:
default double process(double num){
Run Code Online (Sandbox Code Playgroud)
样品:
public class Test {
public static void main(String[] args) {
test(Test::processor1, 1d);
test(Test::processor2, 1d);
}
static double processor1(double num){
return num * 10;
}
static double processor2(double num){
return num * 20;
}
//...
static void test(Function<Double, Double> f, double d){
// Do something util here
System.out.println(f.apply(d));
}
...
Run Code Online (Sandbox Code Playgroud)
现在假设我有一些对象可以提供额外的"处理器"列表.
我正在尝试使用a interface来定义那些额外的"处理器".
static interface IProcessor{
double process(double num);
}
Run Code Online (Sandbox Code Playgroud)
使用附加"处理器"实现对象:
static class SomeObject{
// Just return one but should be a list...
static …Run Code Online (Sandbox Code Playgroud) 假设我在jshell中这样做:
jshell> void printIsEven(int i) {
...> System.out.println(i % 2 == 0);
...> }
| created method printIsEven(int)
jshell> List<Integer> l = Arrays.asList(7,5,4,8,5,9);
l ==> [7, 5, 4, 8, 5, 9]
jshell> l.forEach(/* ??? */); // is it possible to use a method reference here?
Run Code Online (Sandbox Code Playgroud)
在普通程序中,我可以l.forEach(this::printIsEven)在非静态上下文中或l.forEach(MyClass::printIsEven)在名为的类的静态上下文中编写MyClass.
this::printIsEven在jshell中使用不起作用,因为jshell在静态上下文中执行语句,但是你不能使用静态方法引用,因为没有类名称来加前缀::printIsEven,而尝试l.forEach(::printIsEven)只是一个语法错误.
我在"Java - 初学者指南"中阅读了以下代码
interface SomeTest <T>
{
boolean test(T n, T m);
}
class MyClass
{
static <T> boolean myGenMeth(T x, T y)
{
boolean result = false;
// ...
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
以下声明有效
SomeTest <Integer> mRef = MyClass :: <Integer> myGenMeth;
Run Code Online (Sandbox Code Playgroud)
关于上述代码的解释有两点
1 - 当泛型方法被指定为方法引用时,其类型参数
::位于方法名称之前和之后.2 - 如果指定了泛型类,则type参数在类名后面,并在其前面
::.
上面的代码是第一个引用点的示例
有人能为我提供一个实现第二个引用点的代码示例吗?
(基本上我不明白第二个引用点).
Java 8只::通过方法名称启用方法引用.
protected Object loadBeanController(String url) throws IOException {
loader = new FXMLLoader(getClass().getResource(url));
ApplicationContext context = MyProjectClass.getApplicationContext();
loader.setControllerFactory(context::getBean);
return loader.getController();
}
Run Code Online (Sandbox Code Playgroud)
但是,根据BeanFactory接口(Spring)getBean() getBean不采用空参数 - 一些参数值是预期的:
getBean(String name)
getBean(String name,Class requiredType)
getBean(String name,Object [] args)
这是如何解决的?
什么是第二次s.get()返回"ONE"的解释?
String x = "one";
Supplier<String> s = x::toUpperCase;
System.out.println("s.get() = " + s.get());
x = "two";
System.out.println("s.get() = " + s.get());
Run Code Online (Sandbox Code Playgroud)
更新:
比较它:
String x = "one";
Supplier<String> s = () -> x.toUpperCase();
System.out.println("s.get() = " + s.get());
x = "two";
System.out.println("s.get() = " + s.get());
Run Code Online (Sandbox Code Playgroud)
它会抛出一个编译错误.
如何将Java绑定Supplier到Object的现有实例?例如,如果我想compareTo()用这个标题编写我自己的方法:
public static int myCompareTo(Object o1, Object o2, Supplier<Comparable> supplier) {...}
Run Code Online (Sandbox Code Playgroud)
我想能够称之为:
myCompareTo("Hello", "Hello2", String::length);
Run Code Online (Sandbox Code Playgroud)
where String(带大写字母)是一个类而没有对象.那么如何将实例绑定o1到供应商?
我试着做:
public class HelloWorld {
public static void main(String... args){
final String string = "a";
final Supplier<?> supplier = string::isEmpty;
System.out.println(supplier);
}
}
Run Code Online (Sandbox Code Playgroud)
我得到:
HelloWorld$$Lambda$1/471910020@548c4f57
Run Code Online (Sandbox Code Playgroud)
我想拿线isEmpty。我怎样才能做到这一点?
编辑:我创建的方法的代码是此之一:
public class EnumHelper {
private final static String values = "values";
private final static String errorTpl = "Can't find element with value `{0}` for enum {1} using getter {2}()";
public static <T extends Enum<T>, U> T getFromValue(T enumT, U value, String getter) {
@SuppressWarnings("unchecked")
final T[] elements = (T[]) ReflectionHelper.callMethod(enumT, values); …Run Code Online (Sandbox Code Playgroud)