在一个方法中返回多个类型的最符合java的方法是什么?



假设我有一个Java方法,我需要根据条件返回不同的类型。为简单起见,我将提供一个很假的例子:

public (something goes here) processSomething() {
if (condition1) {
return true;
} else if (condition2) {
return 5;
} else {
return new ComplexObject();
}
}

正如您所看到的,我没有定义返回类型以避免对解决方案进行假设。我知道有一些选项,如泛型类型,AnyObject(我可能误解了其中一些可能不适用于我的用例)。

目的是使用上述方法的返回来调用使用Java的反射API (invoke)具有预定义参数的其他方法(如int,booleanString)。

我想知道Java专家最推荐的一个是什么。

创建一个" result holder ";类。像这样:

class OperationResult {
boolean flag;
ComplexObject info;
}

,它在技术上是可行的使用(检查)异常不同的结果,但它不太可能这样的模式是一个不错的选择。

由于Java在指定返回类型时不支持联合类型(这是一个不幸的疏忽,因为它在其他地方支持联合类型),因此必须指定单个返回类型。

根据调用者希望如何响应不同的值,存在各种选项:

  • 如果调用者希望治疗所有类型相同,定义一个常见的超接口的类型,允许调用者,并返回一个
  • 如果呼叫者希望检测和区分类型,您可以:
    • 返回对象,记录类型,并让它们使用instanceof。这不是类型安全的,也就是说,如果你检查了错误的类型,或者如果重构改变了类型
    • ,编译器将不会发出警告。
    • 返回一个类型,该类型提供了所有可能性的getter以及发现所设置的值的方法。这是更安全的类型,但需要注意的是,如果重构后添加额外的类型是安全的。
    • 在调用者提供给您的类型安全回调中传递值,或者返回一个接受访问者的值。这需要更多的设置,并且使用回调可能会给调用者带来不便,但它确实允许任意类型的类型安全切换
    • 通过返回典型值来传递典型值,通过抛出非典型值(可能使用受控异常)来传递非典型值。这对调用者来说比使用回调简单一些,但仍然相当麻烦。在捕获堆栈跟踪(您可以禁用它,但这可能是意料之外的)时,也会有轻微的运行时成本,因此对频繁出现的情况使用它可能不是最优的。如果异常值通常会导致调用方中止其正在执行的操作并将异常升级到其调用方,则此方法特别适合。

第二个技巧的例子:

class FooReturn {
enum Type {
number, 
bool, 
complex
}

final Type type;
int number;
boolean bool;
ComplexType complex;
FooReturn(int x) {
type = number;
number = x;
}
// other constructor and getters
}

使用enum允许类型安全切换,如果在以后的重构中添加或删除了可能的类型,它将提醒调用者:

var value = foo(42);
switch (value.getType()) {
case number:
int n = value.getNumber();
// deal with it
return whatever;
case bool:
if (value.getBool()) {
return doThis();
} else {
return doThat();
}
case complex:
var c = value.getComplex();
return doSomethingComplex(c);
}
throw new AssertionError("Unexpected type: " + value);

调用者当然也可以使用if语句:

var value = foo(42);
if (value.getType() == FooReturn.Type.number) {
dealWithNumbers(42);
} else {
throw new IllegalStateException("This should not be possible :-/");
}

这并不提供穷竭性检查,但如果您只需要处理一小部分情况,则可能很有用。

编辑

目的是使用上述方法的返回来调用使用Java的反射API (invoke)具有预定义参数(如int, boolean和String)的其他方法。

可能不需要区分或类型安全。由于Method.invoke接受Object[]作为参数,因此我只需返回该数组,因此调用者可以这样做:

myMethod.invoke(foo(42));

如果foo方法知道被调用的方法,让它返回一个lambda可能更有意义,因为它可能允许绕过反射的事情,因此更类型安全:

foo(42).run();

其中foo被定义为

Runnable foo(int x) {
if (x == 42) {
return () -> someObject.methodOne();
} else {
return () -> someObject.methodTwo();
}
}

我不是java专家,但我认为传递值的最佳方式是对象,这种值可能是许多类型中的一种。Java为原语值提供了包装类,因此您也可以自由地为它们使用对象。一旦你返回那个对象,你肯定想知道是哪个类型你可以用.getClass()方法知道它。我知道你想要专家的意见,但我很确定你的意见会和我说的差不多。

将其他数据类型转换为对象数据类型


public class types {
public static void main(String[] args) {
System.out.println(multipleTypes(5));
}
static  Object multipleTypes(Object num){
Object numb= 5;
if (numb==num){
return true;
}
else return 5;
}
}
``

相关内容

  • 没有找到相关文章

最新更新