javax.realtime
Class ScopedMemory

java.lang.Object
  extended by javax.realtime.MemoryArea
      extended by javax.realtime.ScopedMemory
Direct Known Subclasses:
LTMemory, LTPhysicalMemory, VTMemory, VTPhysicalMemory

public abstract class ScopedMemory
extends MemoryArea

ScopedMemory is the abstract base class of all classes dealing with representations of memory spaces which have a limited lifetime. In general, objects allocated in scoped memory are freed when (and only when) no schedulable object has access to the objects in the scoped memory.

A ScopedMemory area is a connection to a particular region of memory and reflects the current status of that memory. The object does not necessarily contain direct references to the region of memory. That is implementation dependent.

When a ScopedMemory area is instantiated, the object itself is allocated from the current memory allocation context, but the memory space that object represents (it's backing store) is allocated from memory that is not otherwise directly visible to Java code; e.g., it might be allocated with the C malloc function. This backing store behaves effectively as if it were allocated when the associated scoped memory object is constructed and freed at that scoped memory object's finalization.

The enter() method of ScopedMemory is one mechanism used to make a memory area the current allocation context. The other mechanism for activating a memory area is making it the initial memory area for a real-time thread or async event handler. Entry into the scope is accomplished, for example, by calling the method:

      public void enter(Runnable logic)
 
where logic is a instance of Runnable whose run() method represents the entry point of the code that will run in the new scope. Exit from the scope occurs between the time the runnable.run() method completes and the time control returns from the enter method. By default, allocations of objects within runnable.run() are taken from the backing store of the ScopedMemory.

ScopedMemory is an abstract class, but all specified methods include implementations. The responsibilities of MemoryArea, ScopedMemory and the classes that extend ScopedMemory are not specified. Application code should not extend ScopedMemory without detailed knowledge of its implementation.


Constructor Summary
ScopedMemory(long size)
          Create a new ScopedMemory area with the given parameters.
ScopedMemory(long size, java.lang.Runnable logic)
          Create a new ScopedMemory area with the given parameters.
ScopedMemory(SizeEstimator size)
          Create a new ScopedMemory area with the given parameters.
ScopedMemory(SizeEstimator size, java.lang.Runnable logic)
          Create a new ScopedMemory area with the given parameters.
 
Method Summary
 void enter()
          Associate this memory area with the current schedulable object for the duration of the execution of the run() method of the instance of Runnable given in the constructor.
 void enter(java.lang.Runnable logic)
          Associate this memory area with the current schedulable object for the duration of the execution of the run() method of the given Runnable.
 void executeInArea(java.lang.Runnable logic)
          Execute the run method from the logic parameter using this memory area as the current allocation context.
 long getMaximumSize()
          Get the maximum size this memory area can attain.
 java.lang.Object getPortal()
          Return a reference to the portal object in this instance of ScopedMemory.
 int getReferenceCount()
          Returns the reference count of this ScopedMemory.
 void join()
          Wait until the reference count of this ScopedMemory goes down to zero.
 void join(HighResolutionTime time)
          Wait at most until the time designated by the time parameter for the reference count of this ScopedMemory to drop to zero.
 void joinAndEnter()
          In the error-free case, joinAndEnter combines join();enter(); such that no enter() from another schedulable object can intervene between the two method invocations.
 void joinAndEnter(HighResolutionTime time)
          In the error-free case, joinAndEnter combines join();enter(); such that no enter() from another schedulable object can intervene between the two method invocations.
 void joinAndEnter(java.lang.Runnable logic)
          In the error-free case, joinAndEnter combines join();enter(); such that no enter() from another schedulable object can intervene between the two method invocations.
 void joinAndEnter(java.lang.Runnable logic, HighResolutionTime time)
          In the error-free case, joinAndEnter combines join();enter(); such that no enter() from another schedulable object can intervene between the two method invocations.
 java.lang.Object newArray(java.lang.Class type, int number)
          Allocate an array of the given type in this memory area.
 java.lang.Object newInstance(java.lang.Class type)
          Allocate an object in this memory area.
 java.lang.Object newInstance(java.lang.reflect.Constructor c, java.lang.Object[] args)
          Allocate an object in this memory area.
 void setPortal(java.lang.Object object)
          Sets the portal object of the memory area represented by this instance of ScopedMemory to the given object.
 java.lang.String toString()
          Returns a user-friendly representation of this ScopedMemory of the form Scoped memory # <num> where <num> is a number that uniquely identifies this scoped memory area.
 
Methods inherited from class javax.realtime.MemoryArea
getMemoryArea, memoryConsumed, memoryRemaining, size
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

ScopedMemory

public ScopedMemory(long size)
Create a new ScopedMemory area with the given parameters.

Parameters:
size - The size of the new ScopedMemory area in bytes.
Throws:
java.lang.IllegalArgumentException - Thrown if size is less than zero.
java.lang.OutOfMemoryError - Thrown if there is insufficient memory for the ScopedMemory object or for the backing memory.

ScopedMemory

public ScopedMemory(long size,
                    java.lang.Runnable logic)
Create a new ScopedMemory area with the given parameters.

Parameters:
size - The size of the new ScopedMemory area in bytes.
logic - The Runnable to execute when this ScopedMemory is entered. If logic is null, this constructor is equivalent to constructing the memory area without a logic value.
Throws:
java.lang.IllegalArgumentException - Thrown if size is less than zero.
IllegalAssignmentError - Thrown if storing logic in this would violate the assignment rules.
java.lang.OutOfMemoryError - Thrown if there is insufficient memory for the ScopedMemory object or for the backing memory.

ScopedMemory

public ScopedMemory(SizeEstimator size)
Create a new ScopedMemory area with the given parameters.

Parameters:
size - The size of the new ScopedMemory area estimated by an instance of SizeEstimator.
Throws:
java.lang.IllegalArgumentException - Thrown if size is null, or size.getEstimate() is negative.
java.lang.OutOfMemoryError - Thrown if there is insufficient memory for the ScopedMemory object or for the backing memory.

ScopedMemory

public ScopedMemory(SizeEstimator size,
                    java.lang.Runnable logic)
Create a new ScopedMemory area with the given parameters.

Parameters:
size - The size of the new ScopedMemory area estimated by an instance of SizeEstimator.
logic - The logic which will use the memory represented by this as its initial memory area. If logic is null, this constructor is equivalent to constructing the memory area without a logic value.
Throws:
java.lang.IllegalArgumentException - Thrown if size is null, or size.getEstimate() is negative.
java.lang.OutOfMemoryError - Thrown if there is insufficient memory for the ScopedMemory object or for the backing memory.
IllegalAssignmentError - Thrown if storing logic in this would violate the assignment rules.
Method Detail

enter

public void enter()
Associate this memory area with the current schedulable object for the duration of the execution of the run() method of the instance of Runnable given in the constructor. During this period of execution, this memory area becomes the default allocation context until another default allocation context is selected (using enter, or executeInArea(java.lang.Runnable)) or the enter method exits.

Overrides:
enter in class MemoryArea
Throws:
ScopedCycleException - Thrown if this invocation would break the single parent rule.
ThrowBoundaryError - Thrown when the JVM needs to propagate an exception allocated in this scope to (or through) the memory area of the caller. Storing a reference to that exception would cause an IllegalAssignmentError, so the JVM cannot be permitted to deliver the exception. The ThrowBoundaryError is allocated in the current allocation context and contains information about the exception it replaces.
java.lang.IllegalThreadStateException - Thrown if the caller is a Java thread, or if this method is invoked during finalization of objects in scoped memory and entering this scoped memory area would force deletion of the SO that triggered finalization. This would include the scope containing the SO, and the scope (if any) containing the scope containing the SO.
java.lang.IllegalArgumentException - Thrown if the caller is a schedulable object and no non-null value for logic was supplied when the memory area was constructed.
MemoryAccessError - Thrown if caller is a no-heap schedulable object and this memory area's logic value is allocated in heap memory.

enter

public void enter(java.lang.Runnable logic)
Associate this memory area with the current schedulable object for the duration of the execution of the run() method of the given Runnable. During this period of execution, this memory area becomes the default allocation context until another default allocation context is selected (using enter, or executeInArea(java.lang.Runnable)) or the enter method exits.

Overrides:
enter in class MemoryArea
Parameters:
logic - The Runnable object whose run() method should be invoked.
Throws:
ScopedCycleException - Thrown if this invocation would break the single parent rule.
ThrowBoundaryError - Thrown when the JVM needs to propagate an exception allocated in this scope to (or through) the memory area of the caller. Storing a reference to that exception would cause an IllegalAssignmentError, so the JVM cannot be permitted to deliver the exception. The ThrowBoundaryError is allocated in the current allocation context and contains information about the exception it replaces.
java.lang.IllegalThreadStateException - Thrown if the caller is a Java thread, or if this method is invoked during finalization of objects in scoped memory and entering this scoped memory area would force deletion of the SO that triggered finalization. This would include the scope containing the SO, and the scope (if any) containing the scope containing the SO.
java.lang.IllegalArgumentException - Thrown if the caller is a schedulable object and logic is null.

executeInArea

public void executeInArea(java.lang.Runnable logic)
Execute the run method from the logic parameter using this memory area as the current allocation context. This method behaves as if it moves the allocation context down the scope stack to the occurrence of this.

Overrides:
executeInArea in class MemoryArea
Parameters:
logic - The runnable object whose run() method should be executed.
Throws:
java.lang.IllegalThreadStateException - Thrown if the caller is a Java thread.
InaccessibleAreaException - Thrown if the memory area is not in the schedulable object's scope stack.
java.lang.IllegalArgumentException - Thrown if the caller is a schedulable object and logic is null.

getMaximumSize

public long getMaximumSize()
Get the maximum size this memory area can attain. If this is a fixed size memory area, the returned value will be equal to the initial size.

Returns:
The maximum size attainable.

getPortal

public java.lang.Object getPortal()
Return a reference to the portal object in this instance of ScopedMemory.

Assignment rules are enforced on the value returned by getPortal as if the return value were first stored in an object allocated in the current allocation context, then moved to its final destination.

Returns:
A reference to the portal object or null if there is no portal object. The portal value is always set to null when the contents of the memory are deleted.
Throws:
IllegalAssignmentError - Thrown if a reference to the portal object cannot be stored in the caller's allocation context; that is, if this is "inner" relative to the current allocation context or not on the caller's scope stack.
java.lang.IllegalThreadStateException - Thrown if the caller is a Java thread.

getReferenceCount

public int getReferenceCount()
Returns the reference count of this ScopedMemory.

Note: A reference count of 0 reliably means that the scope is not referenced, but other reference counts are subject to artifacts of lazy/eager maintenance by the implementation.

Returns:
The reference count of this ScopedMemory.

join

public void join()
          throws java.lang.InterruptedException
Wait until the reference count of this ScopedMemory goes down to zero. Return immediately if the memory is unreferenced.

Throws:
java.lang.InterruptedException - If this schedulable object is interrupted by RealtimeThread.interrupt() or AsynchronouslyInterruptedException.fire() while waiting for the reference count to go to zero.
java.lang.IllegalThreadStateException - Thrown if the caller is a Java thread.

join

public void join(HighResolutionTime time)
          throws java.lang.InterruptedException
Wait at most until the time designated by the time parameter for the reference count of this ScopedMemory to drop to zero. Return immediately if the memory area is unreferenced.

Since the time is expressed as a HighResolutionTime, this method is an accurate timer with nanosecond granularity. The actual resolution of the timer and even the quantity it measures depends on the clock associated with time. The delay time may be relative or absolute. If relative, then the delay is the amount of time given by time, and measured by its associated clock. If absolute, then the delay is until the indicated value is reached by the clock. If the given absolute time is less than or equal to the current value of the clock, the call to join returns immediately.

Parameters:
time - If this time is an absolute time, the wait is bounded by that point in time. If the time is a relative time (or a member of the RationalTime subclass of RelativeTime) the wait is bounded by a the specified interval from some time between the time join is called and the time it starts waiting for the reference count to reach zero.
Throws:
java.lang.InterruptedException - If this schedulable object is interrupted by RealtimeThread.interrupt() or AsynchronouslyInterruptedException.fire() while waiting for the reference count to go to zero.
java.lang.IllegalThreadStateException - Thrown if the caller is a Java thread.
java.lang.IllegalArgumentException - Thrown if the caller is a schedulable object and time is null.
java.lang.UnsupportedOperationException - Thrown if the wait operation is not supported using the clock associated with time.

joinAndEnter

public void joinAndEnter()
                  throws java.lang.InterruptedException
In the error-free case, joinAndEnter combines join();enter(); such that no enter() from another schedulable object can intervene between the two method invocations. The resulting method will wait for the reference count on this ScopedMemory to reach zero, then enter the ScopedMemory and execute the run method from logic passed in the constructor. If no instance of Runnable was passed to the memory area's constructor, the method throws IllegalArgumentException immediately.

If multiple threads are waiting in joinAndEnter family methods for a memory area, at most one of them will be released each time the reference count goes to zero.

Note that although joinAndEnter guarantees that the reference count is zero when the schedulable object is released for entry, it does not guarantee that the reference count will remain one for any length of time. A subsequent enter could raise the reference count to two.

Throws:
java.lang.InterruptedException - If this schedulable object is interrupted by RealtimeThread.interrupt() or AsynchronouslyInterruptedException.fire() while waiting for the reference count to go to zero.
java.lang.IllegalThreadStateException - Thrown if the caller is a Java thread, or if this method is invoked during finalization of objects in scoped memory and entering this scoped memory area would force deletion of the SO that triggered finalization. This would include the scope containing the SO, and the scope (if any) containing the scope containing the SO.
ThrowBoundaryError - Thrown when the JVM needs to propagate an exception allocated in this scope to (or through) the memory area of the caller. Storing a reference to that exception would cause an IllegalAssignmentError, so the JVM cannot be permitted to deliver the exception. The ThrowBoundaryError is allocated in the current allocation context and contains information about the exception it replaces.
ScopedCycleException - Thrown if this invocation would break the single parent rule.
java.lang.IllegalArgumentException - Thrown if the caller is a schedulable object and no non-null logic value was supplied to the memory area's constructor.
MemoryAccessError - Thrown if caller is a non-heap schedulable object and this memory area's logic value is allocated in heap memory.

joinAndEnter

public void joinAndEnter(HighResolutionTime time)
                  throws java.lang.InterruptedException
In the error-free case, joinAndEnter combines join();enter(); such that no enter() from another schedulable object can intervene between the two method invocations. The resulting method will wait for the reference count on this ScopedMemory to reach zero, or for the current time to reach the designated time, then enter the ScopedMemory and execute the run method from Runnable object passed to the constructor. If no instance of Runnable was passed to the memory area's constructor, the method throws IllegalArgumentException immediately. *

If multiple threads are waiting in joinAndEnter family methods for a memory area, at most one of them will be released each time the reference count goes to zero.

Since the time is expressed as a HighResolutionTime, this method has an accurate timer with nanosecond granularity. The actual resolution of the timer and even the quantity it measures depends on the clock associated with time. The delay time may be relative or absolute. If relative, then the calling thread is blocked for at most the amount of time given by time, and measured by its associated clock. If absolute, then the time delay is until the indicated value is reached by the clock. If the given absolute time is less than or equal to the current value of the clock, the call to joinAndEnter returns immediately.

Note that although joinAndEnter guarantees that the reference count is zero when the schedulable object is released for entry, it does not guarantee that the reference count will remain one for any length of time. A subsequent enter could raise the reference count to two.

Note that expiration of time may cause control to enter the memory area before its reference count has gone to zero.

Parameters:
time - The time that bounds the wait.
Throws:
ThrowBoundaryError - Thrown when the JVM needs to propagate an exception allocated in this scope to (or through) the memory area of the caller. Storing a reference to that exception would cause an IllegalAssignmentError, so the JVM cannot be permitted to deliver the exception. The ThrowBoundaryError is allocated in the current allocation context and contains information about the exception it replaces.
java.lang.InterruptedException - If this schedulable object is interrupted by RealtimeThread.interrupt() or AsynchronouslyInterruptedException.fire() while waiting for the reference count to go to zero.
java.lang.IllegalThreadStateException - Thrown if the caller is a Java thread, or if this method is invoked during finalization of objects in scoped memory and entering this scoped memory area would force deletion of the SO that triggered finalization. This would include the scope containing the SO, and the scope (if any) containing the scope containing the SO.
ScopedCycleException - Thrown if the caller is a schedulable object and this invocation would break the single parent rule.
java.lang.IllegalArgumentException - Thrown if the caller is a schedulable object, and time is null or no non-null logic value was supplied to the memory area's constructor.
java.lang.UnsupportedOperationException - Thrown if the wait operation is not supported using the clock associated with time.
MemoryAccessError - Thrown if caller is a no-heap schedulable object and this memory area's logic value is allocated in heap memory.

joinAndEnter

public void joinAndEnter(java.lang.Runnable logic)
                  throws java.lang.InterruptedException
In the error-free case, joinAndEnter combines join();enter(); such that no enter() from another schedulable object can intervene between the two method invocations. The resulting method will wait for the reference count on this ScopedMemory to reach zero, then enter the ScopedMemory and execute the run method from logic

If logic is null, throw IllegalArgumentException immediately.

If multiple threads are waiting in joinAndEnter family methods for a memory area, at most one of them will be released each time the reference count goes to zero.

Note that although joinAndEnter guarantees that the reference count is zero when the schedulable object is released for entry, it does not guarantee that the reference count will remain one for any length of time. A subsequent enter could raise the reference count to two.

Parameters:
logic - The Runnable object which contains the code to execute.
Throws:
java.lang.InterruptedException - If this schedulable object is interrupted by RealtimeThread.interrupt() or AsynchronouslyInterruptedException.fire() while waiting for the reference count to go to zero.
java.lang.IllegalThreadStateException - Thrown if the caller is a Java thread, or if this method is invoked during finalization of objects in scoped memory and entering this scoped memory area would force deletion of the SO that triggered finalization. This would include the scope containing the SO, and the scope (if any) containing the scope containing the SO.
ThrowBoundaryError - Thrown when the JVM needs to propagate an exception allocated in this scope to (or through) the memory area of the caller. Storing a reference to that exception would cause an IllegalAssignmentError, so the JVM cannot be permitted to deliver the exception. The ThrowBoundaryError is allocated in the current allocation context and contains information about the exception it replaces.
ScopedCycleException - Thrown if this invocation would break the single parent rule.
java.lang.IllegalArgumentException - Thrown if the caller is a schedulable object and logic is null.

joinAndEnter

public void joinAndEnter(java.lang.Runnable logic,
                         HighResolutionTime time)
                  throws java.lang.InterruptedException
In the error-free case, joinAndEnter combines join();enter(); such that no enter() from another schedulable object can intervene between the two method invocations. The resulting method will wait for the reference count on this ScopedMemory to reach zero, or for the current time to reach the designated time, then enter the ScopedMemory and execute the run method from logic.

Since the time is expressed as a HighResolutionTime, this method is an accurate timer with nanosecond granularity. The actual resolution of the timer and even the quantity it measures depends on the clock associated with time. The delay time may be relative or absolute. If relative, then the delay is the amount of time given by time, and measured by its associated clock. If absolute, then the delay is until the indicated value is reached by the clock. If the given absolute time is less than or equal to the current value of the clock, the call to join returns immediately.

Throws IllegalArgumentException immediately if logic is null.

If multiple threads are waiting in joinAndEnter family methods for a memory area, at most one of them will be released each time the reference count goes to zero.

Note that although joinAndEnter guarantees that the reference count is zero when the schedulable object is released for entry, it does not guarantee that the reference count will remain one for any length of time. A subsequent enter could raise the reference count to two.

Note that expiration of time may cause control to enter the memory area before its reference count has gone to zero.

Parameters:
logic - The Runnable object which contains the code to execute.
time - The time that bounds the wait.
Throws:
java.lang.InterruptedException - If this schedulable object is interrupted by RealtimeThread.interrupt() or AsynchronouslyInterruptedException.fire() while waiting for the reference count to go to zero.
java.lang.IllegalThreadStateException - Thrown if the caller is a Java thread, or if this method is invoked during finalization of objects in scoped memory and entering this scoped memory area would force deletion of the SO that triggered finalization. This would include the scope containing the SO, and the scope (if any) containing the scope containing the SO.
ThrowBoundaryError - Thrown when the JVM needs to propagate an exception allocated in this scope to (or through) the memory area of the caller. Storing a reference to that exception would cause an IllegalAssignmentError, so the JVM cannot be permitted to deliver the exception. The ThrowBoundaryError is allocated in the current allocation context and contains information about the exception it replaces.
ScopedCycleException - Thrown if the caller is a schedulable object and this invocation would break the single parent rule.
java.lang.IllegalArgumentException - Thrown if the caller is a schedulable object and time or logic is null.
java.lang.UnsupportedOperationException - Thrown if the wait operation is not supported using the clock associated with time.

newArray

public java.lang.Object newArray(java.lang.Class type,
                                 int number)
Allocate an array of the given type in this memory area. This method may be concurrently used by multiple threads.

Overrides:
newArray in class MemoryArea
Parameters:
type - The class of the elements of the new array. To create an array of a primitive type use a type such as Integer.TYPE (which would call for an array of the primitive int type.)
number - The number of elements in the new array.
Returns:
A new array of class type, of number elements.
Throws:
java.lang.IllegalArgumentException - Thrown if number is less than zero, type is null, or type is java.lang.Void.TYPE.
java.lang.OutOfMemoryError - Thrown if space in the memory area is exhausted.
java.lang.IllegalThreadStateException - Thrown if the caller is a Java thread.
InaccessibleAreaException - Thrown if the memory area is not in the schedulable object's scope stack.

newInstance

public java.lang.Object newInstance(java.lang.Class type)
                             throws java.lang.IllegalAccessException,
                                    java.lang.InstantiationException
Allocate an object in this memory area. This method may be concurrently used by multiple threads.

Overrides:
newInstance in class MemoryArea
Parameters:
type - The class of which to create a new instance.
Returns:
A new instance of class type.
Throws:
java.lang.IllegalAccessException - The class or initializer is inaccessible.
java.lang.IllegalArgumentException - Thrown if type is null.
java.lang.ExceptionInInitializerError - Thrown if an unexpected exception has occurred in a static initializer
java.lang.OutOfMemoryError - Thrown if space in the memory area is exhausted.
java.lang.InstantiationException - Thrown if the specified class object could not be instantiated. Possible causes are: it is an interface, it is abstract, it is an array, or an exception was thrown by the constructor.
java.lang.IllegalThreadStateException - Thrown if the caller is a Java thread.
InaccessibleAreaException - Thrown if the memory area is not in the schedulable object's scope stack.

newInstance

public java.lang.Object newInstance(java.lang.reflect.Constructor c,
                                    java.lang.Object[] args)
                             throws java.lang.IllegalAccessException,
                                    java.lang.InstantiationException,
                                    java.lang.reflect.InvocationTargetException
Allocate an object in this memory area. This method may be concurrently used by multiple threads.

Overrides:
newInstance in class MemoryArea
Parameters:
c - TThe constructor for the new instance.
args - An array of arguments to pass to the constructor.
Returns:
A new instance of the object constructed by c.
Throws:
java.lang.IllegalAccessException - Thrown if the class or initializer is inaccessible under Java access control.
java.lang.InstantiationException - Thrown if the specified class object could not be instantiated. Possible causes are: it is an interface, it is abstract, it is an array.
java.lang.OutOfMemoryError - Thrown if space in the memory area is exhausted.
java.lang.IllegalArgumentException - Thrown if c is null, or the args array does not contain the number of arguments required by c. A null value of args is treated like an array of length 0.
java.lang.IllegalThreadStateException - Thrown if the caller is a Java thread.
java.lang.reflect.InvocationTargetException - Thrown if the underlying constructor throws an exception.
InaccessibleAreaException - Thrown if the memory area is not in the schedulable object's scope stack.

setPortal

public void setPortal(java.lang.Object object)
Sets the portal object of the memory area represented by this instance of ScopedMemory to the given object. The object must have been allocated in this ScopedMemory instance.

Parameters:
object - The object which will become the portal for this. If null the previous portal object remains the portal object for this or if there was no previous portal object then there is still no portal object for this.
Throws:
java.lang.IllegalThreadStateException - Thrown if the caller is a Java Thread, and object is not null.
IllegalAssignmentError - Thrown if the caller is a schedulable object, and object is not allocated in this scoped memory instance and not null.
InaccessibleAreaException - Thrown if the caller is a schedulable object, this memory area is not in the caller's scope stack and object is not null.

toString

public java.lang.String toString()
Returns a user-friendly representation of this ScopedMemory of the form Scoped memory # <num> where <num> is a number that uniquely identifies this scoped memory area.

Overrides:
toString in class java.lang.Object
Returns:
The string representation