在C#中创建匿名对象的Java等价物是什么?

在C#中创建匿名对象的Java等价物是什么?,c#,java,C#,Java,在C#中,您可以执行以下操作: Object objresult = new Object() { @Override public String toString() { return result.toString(); } } var objResult=new{success=result} 是否有java等价物?匿名类的形式有类似但不完全相同的功能。区别在于它们必须实现一个特定的命名接口或扩展一个命名类 SomeInterface obj = new

在C#中,您可以执行以下操作:

Object objresult = new Object() {
    @Override public String toString() {
        return result.toString(); 
    }
}
var objResult=new{success=result}


是否有java等价物?

匿名类的形式有类似但不完全相同的功能。区别在于它们必须实现一个特定的命名接口或扩展一个命名类

SomeInterface obj = new SomeInterface() {
    // implement the interface
}
因此,为了近似您的示例:

interface Result
{
    bool getSuccess();
}

// ...

bool result = DoSomething();
Result objResult = new Result() {
    bool getSuccess() { return result; }
}
但这个例子没有多少好处


你完全可以把等价物写成

Object objResult = new Object() {
    boolean success = result;
}
在本例中,您所做的是创建
对象
的内联匿名子类,该子类包含一个
成功
字段,该字段实例化为
结果
的值(我假设该字段是布尔值,但可以是任何值)

但是,这不是很有用-因为Java是强类型的,并且您无法引用您创建的匿名类,因此您将无法在任何地方引用
success
变量。匿名子类通常用于实现单个方法接口,或者可能提供超类方法的重写-这两种情况都更有用,因为其他代码可以通过父类/接口上声明的方法调用重写的行为

因此,可能有用的对象的匿名子类可能如下所示:

Object objresult = new Object() {
    @Override public String toString() {
        return result.toString(); 
    }
}
此行为现在已公开,您可以调用
objResult.toString()
,以获得字符串化结果


实际上,最好用
getResult()
方法定义一个接口,然后用一个具体的或匿名的类来实现它。

Java没有通过
var
关键字向C提供类型推断,因此,虽然您可以创建匿名类型,但它们并不是很好,因为您无法获取它们的属性

因此,您可以创建匿名类的实例,如下所示:

Object myobj = new Object() {
  public final boolean success = true;
}
但是由于
myobj
Object
的一个实例,您无法在代码中访问
success
,并且由于您创建了一个匿名类的实例,根据定义,无法显式引用该类

在C#
var中
通过推断类型来解决这一问题,但在Java中无法做到这一点


通常,匿名类用于创建接口和抽象类的实现,因此使用接口或父类作为类型进行引用。

您只是很难再次获取信息:

Object objResult = new Object(){ public final boolean success = result; };
要获取字段,必须使用反射:

objResult.getClass().getDeclaredField("success").getBoolean(objResult)

对于不同类型的字段
success
,您将需要不同的getter来获取值。

Java对于隐式定义类型(通过返回值实现)没有等效的功能。我想最接近的等效代码应该是定义一个“get”方法接口和一个手工实现

interface Result {
    boolean success();
}
Result objResult = new Result() {
    public boolean success() { return result; }
};

对于特定的问题,最好采用更类似Java的方法。C#匿名对象和Java匿名类在名称上相似,但功能不同。

对于Java 10,您可以使用匿名类:

boolean result = true;

var objResult = new Object() {
    boolean success = result;
};

System.out.println(objResult.success);
您可以将它们用于流:

var names = List.of("John", "Peter", "Olaf");

var namesAndLength = names.stream().map(n -> new Object() {
    String name = n;
    int length = n.length();
}).collect(toList());


什么是
success
,什么是
result
?success是字段名,result是一个任意对象,解析为结果变量的当前类型。如果是
int result=3
var obj=new{success=result}obj将是一个只有一个字段的类:int successCorrect。在我的例子中,
success
是一个
Boolean
result
true
false
success
不是一个字段,而是C#中的一个只读属性。是的,我好不容易才发现。正如你所说,我不知道那会有什么好处刚刚看到你的编辑。除了名字之外,它们不是真正相似的功能。这个类是匿名的。接口不是。要阅读这篇文章,你需要为一个简单的类/类型创建一个类文件来扩展可读性,这绝对是愚蠢的。是的,我不太高兴从.Net项目转移到java。。这是nuts@Codebeat可以在声明变量之前声明内部类,甚至本地类,以避免创建整个类文件。可能仍然很笨重,但没有那么疯狂。创建的匿名类具有包可见性。如何在一个不是您创建的匿名类的包中实现这一点?Java总是比C#落后几年。现在要是Java有操作符重载就好了。