我想使用Java 8 的新方法引用在编译时提供一些代码的更多验证.
假设我有一个validateMethod方法需要一个参数:要验证的"方法".例如 :
validateMethod(foo, "methodA");
Run Code Online (Sandbox Code Playgroud)
这里,该方法将在运行时验证foo#methodA()存在.
使用方法引用,我希望能够:
validateMethod(foo::methodA);
Run Code Online (Sandbox Code Playgroud)
因此,该方法的存在将在编译时验证.
问题是似乎必须将方法引用分配给功能接口.例如,这个:
Object dummy = foo::methodA;
Run Code Online (Sandbox Code Playgroud)
生成错误:" 此表达式的目标类型必须是功能接口 ".
如果我创建一个与该methodA方法具有兼容签名的功能接口,它可以工作:
@FunctionalInterface
public interface MyFunctionalInterface
{
public String run();
}
MyFunctionalInterface dummy = foo::methodA;
Run Code Online (Sandbox Code Playgroud)
现在存在的foo#methodA()是在编译时验证的,这就是我想要的!
但...
假设validateMethod不知道它必须验证的方法的签名.那么它仍然可以实现吗?
让我们假装我们不关心歧义和重载方法.在Java 8中是否可以实现某种方法来触发任何方法引用的验证?
例如 :
public class Foo
{
public String methodA()
{
return "methodA";
}
public String methodB(String str)
{
return "methodB";
}
public String methodC(String str, int nbr)
{
return "methodC";
}
}
Foo foo = new Foo();
validateMethod(foo::methodA); // Compile
validateMethod(foo::methodB); // Compile
validateMethod(foo::methodC); // Compile
validateMethod(foo::methodD); // Error!
Run Code Online (Sandbox Code Playgroud)
是否可以以validateMethod接受任何方法引用的方式实现,因此该方法的存在将在编译时验证?
我试过了 :
public void validateMethod(Object obj){}
Run Code Online (Sandbox Code Playgroud)
但它不起作用:" 此表达式的目标类型必须是功能接口 "
这可行:
@FunctionalInterface
public interface MyFunctionalInterface
{
public String run();
}
public void validateMethod(MyFunctionalInterface param){}
Run Code Online (Sandbox Code Playgroud)
但仅适用methodA于Foo类,因为它的签名(无参数)与功能接口的方法签名兼容!
是否有可能以MyFunctionalInterface这样的方式实现功能接口:任何方法引用都是有效参数,因此将在编译时验证?
您认为在编译时验证方法是否存在的任何其他方法?
Ale*_*lev 13
你似乎试图使用方法引用,它实际上是lambda表达式的简写,作为方法文字,它是方法的语法引用(很像Foo.class是对Foo类实例的语法引用).这两个是不一样的,这就是你遇到阻抗的原因.你尝试的是滥用javac编译器完全拒绝的语言功能.
不幸的是,Java中没有方法文字,所以你必须通过其他方法来描述方法,例如Reflection,MethodHandles.Lookup等.我认为很容易想出这种反射检查器,甚至构建注释处理器以在编译时检查给定方法的存在.
| 归档时间: |
|
| 查看次数: |
2226 次 |
| 最近记录: |