What Is an Anonymous Object

What is an Anonymous Object?

The C++ standard does not define the term "anonymous object", but it stands to reason that one might sanely use the term to describe any object that has no name:

  • Temporaries: f(T());
  • Unnamed function parameters: void func(int, int, int);

What I wouldn't count is dynamically-allocated objects:

Technically speaking, an "object" is any region of storage [1.8/1 in 2003], which would include the X bytes making up the integer dynamically-allocated by new int;.

In int* ptr = new int; the pointer (itself an object too, don't forget!) has the name ptr and the integer itself has no name other than *ptr. Still, I'd hesitate to call this an anonymous object.

Again, though, there's no standard terminology.

Scope of methods of an anonymous object - Kotlin

From docs Object Expressions and Declarations:

Note that anonymous objects can be used as types only in local and
private declarations. If you use an anonymous object as a return type
of a public function or the type of a public property, the actual type
of that function or property will be the declared supertype of the
anonymous object, or Any if you didn't declare any supertype. Members
added in the anonymous object will not be accessible.

Demonstrated in code sample below:

class Example4{
val publicObj = object{
val x = 1
}

private val privateObj = object{
val x = 2
}

fun showcase(){
val scopedObj = object{
val x = 3
}
println(publicObj.x) // ERROR : unresolved reference: x
println(privateObj.x) // OK
println(scopedObj.x) // OK
}
}

Differences between Anonymous, Singleton & Companion Object in Scala

This is a quite long answer but I hope it clarifies a bit potential usage scenarios.

So, why Anonymous object is good if we don't want to reuse?

I think that unlike the other two the term "anonymous object" is not well-defined in the Scala world. I can think of several things that might be called so:

  1. Some object that you don't assign to any named variable or field. This can happen in several cases. For example consider foldLeft on some collection. You want to pass the initial value there but you typically don't need to give it any name as this is a disposable object. Another case is when such object contains some piece of logic you want to use (a kind of strategy pattern). Consider following piece from standard ParIterableLike
  def count(p: T => Boolean): Int = {
tasksupport.executeAndWaitResult(new Count(p, splitter))
}

This particular implementation uses named method tasksupport because it wants it to be customizable. But if not that, it might have been something like

  def count(p: T => Boolean): Int = {
new ExecutionContextTaskSupport.executeAndWaitResult(new Count(p, splitter))
}

and new ExecutionContextTaskSupport would be an anonymous object.


  1. Something that should be called an "anonymous type object".

    • This happens quite often if you implement an evidence for some type-classes. Consider this example from Play-Json
case class Resident(name: String, age: Int, role: Option[String])

import play.api.libs.json._
implicit val residentReads = Json.reads[Resident]

// In a request, a JsValue is likely to come from `request.body.asJson`
// or just `request.body` if using the `Action(parse.json)` body parser
val jsonString: JsValue = Json.parse(
"""{
"name" : "Fiver",
"age" : 4
}"""
)

val residentFromJson: JsResult[Resident] = Json.fromJson[Resident](jsonString)

Here the object and the class for residentReads will be generated by a macro behind Json.reads and you don't care what type it has as long as it implements the Reads trait.

  • Or if you have a template method that depends on some strategy returned. I.e these are the cases when all the caller needs to know about the type is that it matches some specified interface contract (i.e. extends certain trait). Consider this piece from ExecutionContextImpl
  def fromExecutorService(es: ExecutorService, reporter: Throwable => Unit = ExecutionContext.defaultReporter):
ExecutionContextImpl with ExecutionContextExecutorService = {
new ExecutionContextImpl(Option(es).getOrElse(createDefaultExecutorService(reporter)), reporter)
with ExecutionContextExecutorService {
final def asExecutorService: ExecutorService = executor.asInstanceOf[ExecutorService]
override def execute(command: Runnable) = executor.execute(command)
override def shutdown() { asExecutorService.shutdown() }
override def shutdownNow() = asExecutorService.shutdownNow()
override def isShutdown = asExecutorService.isShutdown
override def isTerminated = asExecutorService.isTerminated
override def awaitTermination(l: Long, timeUnit: TimeUnit) = asExecutorService.awaitTermination(l, timeUnit)
override def submit[T](callable: Callable[T]) = asExecutorService.submit(callable)
override def submit[T](runnable: Runnable, t: T) = asExecutorService.submit(runnable, t)
override def submit(runnable: Runnable) = asExecutorService.submit(runnable)
override def invokeAll[T](callables: Collection[_ <: Callable[T]]) = asExecutorService.invokeAll(callables)
override def invokeAll[T](callables: Collection[_ <: Callable[T]], l: Long, timeUnit: TimeUnit) = asExecutorService.invokeAll(callables, l, timeUnit)
override def invokeAny[T](callables: Collection[_ <: Callable[T]]) = asExecutorService.invokeAny(callables)
override def invokeAny[T](callables: Collection[_ <: Callable[T]], l: Long, timeUnit: TimeUnit) = asExecutorService.invokeAny(callables, l, timeUnit)
}
}

Again the caller don't care of the specific type as long as it meets the contract of ExecutionContextExecutorService and particularly we don't care that it is based on ExecutionContextImpl rather than any other implementation.

And actually case #1 and #2 (i.e. "an anonymous object of an anonymous type") are often combined if you need to pass somewhere a piece of work that for some reasons doesn't fit simple Function interface (either because it needs more than one life-cycle method or for historical compatibility reasons). The prime example of this is java.lang.Runnable. And here is another example from ExecutionContextImpl:

// As per ThreadFactory contract newThread should return `null` if cannot create new thread.
def newThread(runnable: Runnable): Thread =
if (reserveThread())
wire(new Thread(new Runnable {
// We have to decrement the current thread count when the thread exits
override def run() = try runnable.run() finally deregisterThread()
})) else null

The Thread class requires Runnable as a piece of work to execute and we want to wrap the runnable we've got as a parameter with another one that will call deregisterThread at the end but we don't care about the name of the object or its actual type.

what's the real purpose of Companion Object?

I can think of several major reasons to use Companion Objects.

  1. Something that in Java world would be a static method or a static field. For instance assume you write you custom arbitrary-precision arithmetic BigInt. Where would you put well-known constants such as zero so they would be accessible from the outside? The companion object is the answer. Another quite typical usage for this kind of companion objects is means to provide some factory methods (typically via apply) so for example you can write
 List.empty
List(1, 2, 3)

without the new keyword


  1. You have some class and you want to provide some shared default instance for it. It is not necessary a singleton in terms that you are quite OK with creating more instances of that class. For example scala.util.Random defines both class and a companion object as
object Random extends Random

so you can do just

Random.nextInt

  1. Something that is probably most deservedly might be called a "companion object". You have some hierarchy of classes and a piece of logic that should be bound to each class in the hierarchy but is not of the type of the classes in the hierarchy. This might sound a bit complicated but is not that hard. The scala.concurrent package employs this idea a lot. Consider for example:
abstract class GenTraversableFactory[CC[X] <: GenTraversable[X] with GenericTraversableTemplate[X, CC]]
extends GenericCompanion[CC] {

private[this] val ReusableCBFInstance: GenericCanBuildFrom[Nothing] = new GenericCanBuildFrom[Nothing] {
override def apply() = newBuilder[Nothing]
}
def ReusableCBF: GenericCanBuildFrom[Nothing] = ReusableCBFInstance

// some other stuff

}

which a few levels down to inheritance tree is implemented by the List companion object

object List extends SeqFactory[List] {
/** $genericCanBuildFromInfo */
implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, List[A]] =
ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]]

def newBuilder[A]: Builder[A, List[A]] = new ListBuffer[A]

// some other stuff

}

This canBuildFrom is actually used by many collection methods that transform them into other collections such as ++ or map. Moreover this clever trick allows you to write something like this with mapping to other collection type:

val list: List[Int] = Vector(1, 2, 3).map(x => 2 * x)(breakout)

c# anonymous object, why only sometimes contains the field definitions?

This isn't specific to anonymous types. Everything inherits from object which means that you can implicitly cast anything as object.

Calling a method that returns an anonymous type and assigning it to a variable declared as object is the same as doing this:

object obj = new { avg = 2, hi = 3, lo = 1 };

object doesn't have properties like avg, hi, etc., so Visual Studio doesn't display them and if you type them they won't compile.

To illustrate using something other than an anonymous type:

var s = "Hello!";
object o = s;

There's only one string. Both s and o refer to a string. But s is cast as a string and o is cast as an object.

So you can do this:

var s = "Hello!";
object o = s;
var l = s.Length;

...but you can't do this:

var s = "Hello!";
object o = s;
var l = o.Length; // object doesn't have a Length property.

If you do this:

    var obj = new { avg = 2, hi = 3, lo = 1};

...using var means that the type is inferred. Whatever you're assigning to it, that's what the type is. In this case, behind the scenes, the compiler is actually creating a new type, so it behaves as if you had defined a type with those properties.

Anonymous types like this are handy for use within a method, but they're not meant for passing values between methods. For that either a class, struct, or tuple is better.

Creating an anonymous object who must have the dot in Key name and put it inside another anonymous object

Solved using Dictionary, then passed it inside an anonymous type obj:

IDictionary highlitsFieldsContainer = new Dictionary<string, object>();
// ... some code
highlitsFieldsContainer["bodyText.exact"] = new { };
highlitsFieldsContainer["title.exact"] = new { };
var fieldsContainer = new
{
fields = highlitsFieldsContainer,
};

// OUTPUT: fieldsContainer = { fields = { bodyText.exact = {}, title.exact = {} } }

And used a RouteValueDictionary class to read that values when elasticsearch send his response.

RouteValueDictionary _res = new RouteValueDictionary(dynamicResponse.highlights);
if (_res["shortDescription.exact"] != null)
{
// ...
}

When does the anonymous objects get deleted from memory and when it is recommended to use them?

“Anonymous object” is not a standard term, it's a descriptive term. I would interpret it as an object without a name. Objects with names are called variables or data members.

  1. In the expression MyClass().disp() you're calling the member function disp on a temporary object of class MyClass. The lifetime of the temporary object extends [1]to the end of the full expression. Which in C++ standardese, if I recall correctly, is called the full-expression.

  2. The new-expression new MyClass allocates memory for a new MyClass object, and creates a new MyClass object in that chunk of memory. The expression produces a pointer to the new object. You can store that pointer in a variable and use it in a later delete expression to destroy the object and deallocate its memory.

  3. The expression new MyClass(300) is the same except an argument is provided for the MyClass constructor. The new-expression syntax also provides a notation to specify arguments to the allocation operation. But that's more advanced, very seldom needed, and anyway, as a beginner you should preferentially never use raw new or delete, but instead standard library containers and strings.

If there is no corresponding delete for a new then the object lives till the end of the program execution. If this is a machine with an operating system then the OS will reclaim the memory. However, the OS knows nothing about C++ objects so the object destructor is then not called, and hence cleanup specified in the destructor will not be performed.

You ask where new is useful. Generally when the desired lifetime for an object does not fit a scope (the nested lifetimes of local automatic variables), and/or where one needs a dynamic size object. Using new to control lifetime is less of an issue with efficiently movable objects as in C++11 and later, and for dynamic size preferentially use containers such as std::vector and strings like std::string.


[1] More generally a temporary object can be bound directly to a local reference, in which case its lifetime is extended to the lifetime of the reference, i.e. out the enclosing block.

Can you create a Java array of an anonymous class?

Remember that new Object() {...} gives you a value not a type.

So, here is how you could create an array of instances of anonymous classes:

final Object[] anonArray = new Object[]{
new Object(){
public String foo = "bar1";
},
new Object(){
public String foo = "bar2";
},
new Object(){
public String foo = "bar3";
},
new Object(){
public String foo = "bar4";
}
};

Or if you want an array with the same anonymous class instance 4 times:

final Object anonInstance = new Object(){
public String foo = "bar1";
};
final Object[] anonArray = new Object[]{
anonInstance, anonInstance, anonInstance, anonInstance
};

Or if you want 4 distinct instances of the same anonymous class:

final Object[] anonArray = new Object[4];
for (int i = 0; i < anonArray.length; i++) {

// Just to show we can do this ....
final String bar = "bar" + 1;

anonArray[i] = new Object(){
public String foo = bar; // Look!
};
}

Note that in all of the above the array type is Object[] not "array of the anonymous subclass of Object". It is difficult to conceive that this would matter, but if it did matter you would need to resort to reflection to create the array class. (See @ernest_k's answer.)

Or just declare an array of an appropriate custom class or interface, and create anon subclasses from that class / interface. Anonymous subclasses of Object are not exactly practical ...

Anonymous object Creation and GC

If an instance is not available (reachable) within the code, then it's dead. When the gc runs, it identifies the live set, not the set of dead objects. The JVM has its own way of keeping track of live objects.
The collector will trace the live set, marking all live objects.
Then the collector will, depending on the type, either move the live set to another memory area (copying collector) or traverse the heap, deleting dead objects as it finds them and optionally compacting the heap.

In your specific case, the fact that an anonymous object has no specific reference doesn't really matter to the gc since it has its way of keeping track of live and dead objects.



Related Topics



Leave a reply



Submit