简体   繁体   English

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

[英]What is the Java equivalent of creating an anonymous object in C#?

In C#, you can do the following: 在C#中,您可以执行以下操作:

var objResult = new { success = result };

Is there a java equivalent for this? 这有一个java等价物吗?

Java does not have type inference provided to C# by the var keyword, so whilst you can create anonymous types they're not much good since you can't get at their attributes. Java没有通过var关键字向C#提供类型推断,因此虽然您可以创建匿名类型,但由于您无法获取其属性,因此它们并不是很好。

So you can create an instance of an anonymous class like so: 所以你可以像这样创建一个匿名类的实例:

Object myobj = new Object() {
  public final boolean success = true;
}

But since myobj is an instance of Object you can't access success in your code, and as you have created an instance of an anonymous class there is by definition no way to explicitly refer to this class. 但是由于myobjObject一个实例,你无法在代码中访问success ,并且因为你创建了一个匿名类的实例,所以根据定义没有办法显式引用这个类。

In C# var solves this by inferring the type but there is no way to do this in Java. 在C# var通过推断类型来解决这个问题,但是在Java中无法做到这一点。

Normally anonymous classes are used to create implementations of interfaces and abstract classes and so are referenced using the interface or parent class as the type. 通常,匿名类用于创建接口和抽象类的实现,因此使用接口或父类作为类型进行引用。

With Java 10 you can use anonymous classes: 使用Java 10,您可以使用匿名类:

boolean result = true;

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

System.out.println(objResult.success);

You can use them with streams: 您可以将它们与流一起使用:

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

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

https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html

https://developer.oracle.com/java/jdk-10-local-variable-type-inference https://developer.oracle.com/java/jdk-10-local-variable-type-in​​ference

You can definitely write the equivalent as 你绝对可以写出等价的

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

What you've done in this case is create an inline anonymous subclass of Object , which contains a success field instantiated to the value of result (which I've assumed is a boolean here, but could be anything). 你在这种情况下所做的是创建一个Object的内联匿名子类,它包含一个实例化为result值的success字段(我假设这里是一个布尔值,但可以是任何东西)。

However, this isn't very useful - since Java is strongly typed, and you have no way to refer to the anonymous class you created, you won't be able to refer to the success variable anywhere. 但是,这不是很有用 - 因为Java是强类型的,并且您无法引用您创建的匿名类,您将无法在任何地方引用success变量。 Anonymous subclasses are generally used to either implement single-method interfaces, or perhaps provide an override of a superclass method - both of these cases are more useful since other code can invoke the overridden behaviour via the method declared on the parent class/interface. 匿名子类通常用于实现单方法接口,或者可能提供超类方法的覆盖 - 这两种情况都更有用,因为其他代码可以通过父类/接口上声明的方法调用重写行为。

So an anonymous subclass of Object which might be useful could be something like the following: 所以Object的匿名子类可能有用,可能如下所示:

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

This behaviour is now exposed as you can call objResult.toString() in order to get the stringified result out. 此行为现​​在公开,因为您可以调用objResult.toString()以获取字符串化结果。

In practice it would be better to define an interface with a getResult() method instead, and then implement this with either a concrete or anonymous class. 在实践中,最好使用getResult()方法定义接口,然后使用具体或匿名类实现此接口。

You just have a harder time getting the information out again: 您只是更难以再次获取信息:

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

To get the fields you have to use reflection: 要获取字段,您必须使用反射:

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

For different types of the field success you will need different getters for the value. 对于不同类型的现场success您将需要不同的值来获取。

There is similar but not identical functionality in the form of anonymous classes. 匿名类的形式有类似但不相同的功能。 The difference being that they have to implement a particular named interface or extend a named class. 不同之处在于它们必须实现特定的命名接口或扩展命名类。

SomeInterface obj = new SomeInterface() {
    // implement the interface
}

So, to approximate your example: 所以,要近似你的例子:

interface Result
{
    bool getSuccess();
}

// ...

bool result = DoSomething();
Result objResult = new Result() {
    bool getSuccess() { return result; }
}

But there is not much gain for this example. 但是这个例子并没有太大的收获。

http://www.docstore.mik.ua/orelly/java-ent/jnut/ch03_12.htm http://www.docstore.mik.ua/orelly/java-ent/jnut/ch03_12.htm

Java has no equivalent feature for implicitly defining types with implemented by returning values. Java没有等效的功能来隐式定义通过返回值实现的类型。 I guess the closest equivalent code would be to define an interface of "get" methods together with a handmade implementation. 我想最接近的等效代码是将“get”方法的接口与手工实现一起定义。

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

You are probably better off taking a more Java-like approach to the specific problem. 你可能最好采取类似Java的方法来解决具体问题。 C# anonymous objects and Java anonymous classes are similar in name, but not functionality. C#匿名对象和Java匿名类的名称相似,但功能不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM