The Java Language Specification says:
An object is a class instance or an array.
And it also says:
arrays [...] may be assigned to variables of type Object
But the part that confuses me is:
The class Object is a superclass of all other classes
If arrays may be assigned to variables of type Object, then it must mean that arrays can be Objects (not only behave as, but to be instead). Then it means that an array is a class instance, which does not seem to be consistent with the first quote (if it were, then why would it be listed as a different thing?).
How can all this fit together?
There is no contradiction.
An array is also an Object, albeit a special kind of Object.
It is like saying: An bird is also an animal, albeit a special kind of animal.
You can convince yourself by compiling and running the following Java code.
String[] arrayOfStrings = { "bla", "blah" };
// examine the class hierarchy of the array
System.out.println("arrayOfStrings is of type "
+ arrayOfStrings.getClass().getSimpleName()
+ " which extends from "
+ arrayOfStrings.getClass().getSuperclass().getSimpleName());
// assingning the array to a variable of type Object
Object object = arrayOfStrings;
The output will be
arrayOfStrings is of type String[] which extends from Object
Arrays are special classes provided to you by Java itself. All of them inherit from common superclass Object. As they inherit from Object they of course can be used anywhere where Object is expected. Instances of arrays are indeed instances of those classes. One can even reference array classes as they do with other classes' literals:
Class<int[]> intArrayClass = int[].class;
I see no conflict.
This can be useful https://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html#jls-10.8
Yes... and no. It is true, indeed, that new Object[100] instanceof Object → true, but this is missing the true nature of arrays in Java. Arrays are objects (lowercase), but not Objects (capitalized). Being objects, for example, you have to use the new operator to allocate space for them.
However, the Java Language Specification is right to say that "An object is a class instance or an array", because arrays are fundamentally different from a regular Object. They are inherited from languages such as C++, that were much more deeply rooted in the low-level architecture of computers.
"arrays [...] may be assigned to variables of type Object" only because Java provides an interface for us, programmers, to refer to arrays as Objects. In fact, the JLS says:
All methods of class Object may be invoked on an array
Which of course is true, but it does not logically imply they are Objects. Arrays are not true Objects; therefore, they are not true class instances, and therefore the sentence "The class Object is a superclass of all other classes" doesn't apply here.
All in all, Java is not a pure Object-Oriented programming language (primitives are not objects, for example, but they are nonetheless present in Java). And arrays are a language feature that Java includes that behave as if they were class instances of the Object class, but are not actually class instances of it.
[This is my attempt at summarising the main points made here. Thanks a lot to all of you for your ideas, and feel free to add more!]
The class Object is a superclass of all other classes
All classes in Java extend Object. The class name is actually Object (proper name capitalized). It's why all classes have the method toString() and hashCode(), because they all inherited it from Object.class
An object is a class instance or an array.
An object (lowercase, not a proper name) is the instance generated by the new keyword. ie: File is a class and when you call new File() you just made a File object. I honestly think they should have called it a class instance. (clarification: I wish they never called an instance an object)
arrays [...] may be assigned to variables of type Object
Object[] is an array that can contain instances of type Object.
Object[] obj = new Object[100];
obj instanceof Object evaluates to true.
Your second link also says:
All methods of class Object may be invoked on an array.
So from a dev's POV, at least, it's an Object though there is no java.lang.Array (that is exposed to us) it has been instanced from.
A second indication is that arrays are also stored on the heap.
Related
The question is basically self-explanatory. I haven't been able to find an API for arrays (other than this Arrays, but this just defines a bunch of static helper functions for dealing with actual arrays). If there is no class for it, this seems to suggest that an array can't be an Object.
However, the fact that an array has public fields like length and methods that it can invoke like .equals() and .clone() seem to suggest (very strongly) the complete opposite.
What is the explanation for the odd presentation and behavior of primitive arrays?
As a note, I tried to use the "Open Implementation" Eclipse feature on the .clone() method of an array just now, hoping that I would be able to look at where and how this method was defined (since it said int[] overrode it from Object), but it actually caused my entire Eclipse to freeze up and crash...
There is a class for every array type, so there's a class for int[], there's a class for Foo[]. These classes are created by JVM. You can access them by int[].class, Foo[].class. The direct super class of these classes are Object.class
public static void main(String[] args)
{
test(int[].class);
test(String[].class);
}
static void test(Class clazz)
{
System.out.println(clazz.getName());
System.out.println(clazz.getSuperclass());
for(Class face : clazz.getInterfaces())
System.out.println(face);
}
There's also a compile-time subtyping rule, if A is subtype of B, A[] is subtype of B[].
The Java Language Specification should give you an idea:
The direct superclass of an array type is Object.
Every array type implements the interfaces Cloneable and java.io.Serializable.
Moreover:
An object is a class instance or an array.
So arrays are not instances and therefore you don't need a constructor to create them. Instead you use the Array Creation Expressions.
See the below code. It compiles:
int[] arr = new int[2];
System.out.println(arr.toString());
Now, on any primitive type, you cannot call a method(toString()) defined in Object class (Or, any method for that matter)... So, an array is essentially an Object.
OK, here you go:
From the JLS Section 4.3:
There are four kinds of reference types: class types (§8), interface
types (§9), type variables (§4.4), and array types (§10).
And, Section 10:
In the Java programming language, arrays are objects (§4.3.1), are
dynamically created, and may be assigned to variables of type Object
(§4.3.2). All methods of class Object may be invoked on an array.
So, from the first quote, Array is not actually a class... It is another type. But, essentially arrays are objects, though not of some Class, but they are of Array type. So they are not instances of some class, and may be objects of array are defined to be created that way...
So short and simple, yes <Type>[] is a type of Object. It extends directly from Object as I understand it. There are all the Object methods on it, toString(), hashCode(), ... Plus a special exposed variable called length. The class java.util.Arrays is a utility class for dealing with types of Arrays. It's a little confusing when you add to the mess things like: int[] does not inherit from Object[]. Also, unlike other Object types, there are no constructors for array types. They respect the new keyword but that is usually to allocate for the size. It's a little bizarre, but just one of those language quirks.
To answer the question though, yes they are an object.
An array is a container object that holds a fixed number of values of a single type.
See http://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
Only those several primitive types in Java as we known. Basically, we still have several steps to create an array, such as declare, construct or initialize if needed, and that means array is an object indeed.
Stepping deeper, the primitive types could be stored in memory with the original values but object is an address(reference). So we can imagine a paradox, how could we store the original values in the memory if the array is an primitive type? I think the same as String, but String is a final object so that you can construct an object in an easy way, String s = "s", like a primitive type.
It is an object
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
Sample code:
PrintMethod.java
public class PrintMethod {
void print (String s) {
System.out.print(s);
}
}
PrintS.java
class PrintS {
public static void main(String[] args) {
PrintMethod pm = new PrintMethod(); //i know this is how you make a new object, but
pm.print("Hello");
}
}
Where is the object here? I've looked all over the internet, but what my teacher is telling me is different from what I found. Help?
And what then is the difference between an object and a class? If PrintS and PrintMethod are objects as well? I thought an object was an instance of a class? I'm so sorry, I just need this topic to be crystal clear.
I think the best answer you can get can be found in the official docs:
The new operator instantiates a class by allocating memory for a new
object and returning a reference to that memory. The new operator also
invokes the object constructor.
Note: The phrase "instantiating a class" means the same thing as
"creating an object." When you create an object, you are creating an
"instance" of a class, therefore "instantiating" a class.
The new operator returns a reference to the object it created.
In your case, pm is a reference to an object of type PrintMethod. When you do pm = new PrintMethod() you are constructing a new object.
See the part of Using Objects in the official docs.
Clarification: When you say class, you usually refer to the code, it is simply a piece of code. But when you say object, you mean an instance of the class. Every object "belongs" to a class.
For example, consider a class named Car. All cars have wheels. An instance of Car would be a specific car, say toyota. So toyota is now an instance of Car.
An Object is the blueprint of a Class that gets created in Heap Memory. To get access to those objects we use references in Java Code.
So we don't directly access objects in Java Code. It is the reference that we access and use.
In your case pm is just an reference to a instance of PrintMethod placed in Heap memory. But "Hello" is a literal instance of a String that gets created in String pool.
PrintMethod pm = new PrintMethod();
the left side part is called as Declaration and the right side part is called reference,where new which allocated the memory>
We can define Object in 4 ways .
1) An Object is an Instance of a class ( Instance is nothing but allocating sufficient amount memory space for the data members and methods of a class )
2) Each and every class variable are also known as objects .
3) Blue print of a class is known as an object .
4) Each and every grouped Item is known as an object ( You know a grouped item is a variable which allows us to store multiple values of same type or different type or both at once )
So.,
Here i will give a small explanation about what is a object .
dear friend " Have you seen a Tree" ?????
Most of the people say that they have seen a tree . But Answer is Nooooo....
You never seen a tree but you have seen Types of tree like Banana Tree, Apple tree... etc
So here if you understand there is a very good beauty in it .
So a tree is a plan and Types of trees are Objects . So, Now tell me does a tree exists . Nooo its just a plan and based on that plan types of trees can be planted .
A class is a blue print and based on a class many objects can be created . So Always remember that "A class has Logical Existence " and "an Object has Physical Existence "
Objects are building blocks of an OO program. A program that uses OO technology is basically a collection of objects.
Each Object is made up of the Data & Behavior.
Object Data: the Data stored within an object represents the state of the Object. In OO programming terminology, this data is called Attributes.
Object Behavior: The behavior of an object is what the object can do. In OO programming terminology, these behaviors contained in methods, and you invoke a method by sending a message to it.
Also i agree with the "Maroun Maroun."
The question is basically self-explanatory. I haven't been able to find an API for arrays (other than this Arrays, but this just defines a bunch of static helper functions for dealing with actual arrays). If there is no class for it, this seems to suggest that an array can't be an Object.
However, the fact that an array has public fields like length and methods that it can invoke like .equals() and .clone() seem to suggest (very strongly) the complete opposite.
What is the explanation for the odd presentation and behavior of primitive arrays?
As a note, I tried to use the "Open Implementation" Eclipse feature on the .clone() method of an array just now, hoping that I would be able to look at where and how this method was defined (since it said int[] overrode it from Object), but it actually caused my entire Eclipse to freeze up and crash...
There is a class for every array type, so there's a class for int[], there's a class for Foo[]. These classes are created by JVM. You can access them by int[].class, Foo[].class. The direct super class of these classes are Object.class
public static void main(String[] args)
{
test(int[].class);
test(String[].class);
}
static void test(Class clazz)
{
System.out.println(clazz.getName());
System.out.println(clazz.getSuperclass());
for(Class face : clazz.getInterfaces())
System.out.println(face);
}
There's also a compile-time subtyping rule, if A is subtype of B, A[] is subtype of B[].
The Java Language Specification should give you an idea:
The direct superclass of an array type is Object.
Every array type implements the interfaces Cloneable and java.io.Serializable.
Moreover:
An object is a class instance or an array.
So arrays are not instances and therefore you don't need a constructor to create them. Instead you use the Array Creation Expressions.
See the below code. It compiles:
int[] arr = new int[2];
System.out.println(arr.toString());
Now, on any primitive type, you cannot call a method(toString()) defined in Object class (Or, any method for that matter)... So, an array is essentially an Object.
OK, here you go:
From the JLS Section 4.3:
There are four kinds of reference types: class types (§8), interface
types (§9), type variables (§4.4), and array types (§10).
And, Section 10:
In the Java programming language, arrays are objects (§4.3.1), are
dynamically created, and may be assigned to variables of type Object
(§4.3.2). All methods of class Object may be invoked on an array.
So, from the first quote, Array is not actually a class... It is another type. But, essentially arrays are objects, though not of some Class, but they are of Array type. So they are not instances of some class, and may be objects of array are defined to be created that way...
So short and simple, yes <Type>[] is a type of Object. It extends directly from Object as I understand it. There are all the Object methods on it, toString(), hashCode(), ... Plus a special exposed variable called length. The class java.util.Arrays is a utility class for dealing with types of Arrays. It's a little confusing when you add to the mess things like: int[] does not inherit from Object[]. Also, unlike other Object types, there are no constructors for array types. They respect the new keyword but that is usually to allocate for the size. It's a little bizarre, but just one of those language quirks.
To answer the question though, yes they are an object.
An array is a container object that holds a fixed number of values of a single type.
See http://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
Only those several primitive types in Java as we known. Basically, we still have several steps to create an array, such as declare, construct or initialize if needed, and that means array is an object indeed.
Stepping deeper, the primitive types could be stored in memory with the original values but object is an address(reference). So we can imagine a paradox, how could we store the original values in the memory if the array is an primitive type? I think the same as String, but String is a final object so that you can construct an object in an easy way, String s = "s", like a primitive type.
It is an object
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
If one needs to use a Class<T> as part of a key of a Map what is the proper way to define the hashCode and equals?
A Class<T> inherits the ones from Object which check for reference equality and return the memory address as the hashcode but in my mind it is not clear what is the meaningful definition of equals and hashCode definition of a Class<T>.
Should I use theClass.getClass().hashCode(); for example (where we have Class<T> theClass;) to use the actual instance's methods?
But this does not seem to be the correct thing to do.
For example in the javadoc for Class<T>:
Every array also belongs to a class that is reflected as a Class
object that is shared by all arrays with the same element type and
number of dimensions
So it seems in some cases the same Class<T> is shared among objects? So what would be the way to follow? Perhaps use theClass.hashCode() and theClass.equals() to use reference equality? Not sure at all here.
The implementation of hashCode and equals java.lang.Class inherits from java.lang.Object is meaningful and usually appropriate, as all instances of a class are guaranteed to return the same Class object from getClass(), i.e.
new Integer(2).getClass() == new Integer(3).getClass();
This is somewhat buried in the docs; the javadoc of getClass() writes:
Returns:
The Class object that represents the runtime class of this object.
See Also:
Literals, section 15.8.2 of The Java™ Language Specification.
That section writes:
A class literal evaluates to the Class object for the named type (or for void) as defined by the defining class loader (§12.2) of the class of the current instance.
and section 12.2 writes:
Well-behaved class loaders maintain these properties:
Given the same name, a good class loader should always return the same class object.
...
A malicious class loader could violate these properties. However, it could not undermine the security of the type system, because the Java virtual machine guards against this.
And yes, if the same class definition is loaded by different class loaders, the class objects will not be equal. As the runtime treats these as independent classes (who just happen to share the same name, but need not otherwise be similar, let alone binary compatible), this is usually desired.
The method String getName() returns a unique String representation of the Class. You can use this String for equals/hashCode as an ordinary String if your program does not use more than one classloader.
Clearly these are a class, right? But I can't find any javadoc api's on them. I can find an Arrays class which offers methods to work with these types of arrays, but not an actual class for these. I've always been confused about this.
They are an instance of int[].class
new int[]{1,2,3,4} instanceof int[]; // true
From Java Language Specification
In the Java programming language arrays are objects (§4.3.1), are dynamically created, and may be assigned to variables of type Object (§4.3.2). All methods of class Object may be invoked on an array.
"new int[4]" is an instance of the class called [I which is the class of one dimensional integer array. Every one dimensional integer array is an instance of this class
new int[x][y] is an instance of the class called [[I.
new int[x][y][z] is an instance of the class called [[[I.
Notice the pattern here?
Under the hood JMV has a metaclass from which array types like [I, [[I or [[[I are instanced at the time of need. Same logic applies to the all primitive types.