Does an annotation object extend the Object class in java? - java

I know that an annotation object is created implicitly by the JVM. Also, I know that all objects in java inherit the superclass Object. However, if by reflection you retrieve an annotation object, it doesn't seem to have the methods finalise() and clone() which are defined by the Object class in java. Does an annotation object indeed inherit the Object class? Is there a reason why an annotation object doesn't define those methods?
An example code snippet here:
Class<autobot> jane = autobot.class;
about frank = jane.getAnnotation(about.class);
frank.clone(); // This generates an error
frank.finalize(); // This generates an error
Where "autobot" is an annotated class and "about" is the annotation type.

It does. clone() and finalize() aren't public. This doesn't work either:
Object o = new Object();
o.clone(); // nope
o.finalize(); // nope
It may work on certain classes. For example, this DOES work:
ArrayList<String> o = new ArrayList<String>();
o.clone();
That's simply because class ArrayList itself has overridden the clone() method and made it public. You can override a method and make it more public (you can't make em less public).
The type def of an annotation doesn't make anything more public.

Related

Is constructor the only way to create the object of a class in JAVA?

If a constructor is the only way to create the object of a class then how
String name = "Java";
is able to create an object of String class even without using constructor.
No. Constructor is not the only way.
There are at least two more ways:
Clone the object
Serialize and then deserialize object.
Though in case with your example - neither of these is used.
In this case Java uses string pool
There is another way of creating objects via
Class.forName("fully.qualified.class.name.here").newInstance()
Class.forName("fully.qualified.class.name.here").getConstuctor().newInstance()
but they call constructor under the hood.
Other ways to create objects are cloning via clone() method and deserialization.
I suppose in a loop-hole type of way you could use the class object too:
// Get the class object using an object you already have
Class<?> clazz = object.getClass();
// or get class object using the type
Class<?> clazz = Object.class;
// Get the constructor object (give arguments
// of Class objects of types if the constructor takes arguments)
Constructor<?> constructor = clazz.getConstructor();
// then invoke it (and pass arguments if need be)
Object o = constructor.newInstance();
I mean you still use the constructor so it probably doesn't really count. But hey, its there!
Java doc link for Class object
YES, each time a new object is created, at least one constructor will be invoked.
Look at this tutorial, this will explain all with objects, classes and constructors.

How does Object.toString() work for different underlying types?

I don't understand why this works in java:
If I have an Integer object in a object, example:
Object myIntObj = new Integer(5);
Now if i do:
System.out.println(myIntObj);
the output is: 5
I now that the Integer class has an ovveride of the toString method but in this case is different (I think).
For the polymorphism, if I have a "child object" in a "father variable" the object doesn't change its real type (in this case Integer) But... it (in the Object variable) can just use the method of the Object Class, so why if I write:
System.out.println(myIntObj);
I can see directly the number 5 and not the reference of this object? Because toString method in the object class by default return just a string of the reference of the object.
like:
Object currentPlayer = new Player();
System.out.println(currentPlayer);
In this case the output is the reference of the Player objecet because is called the toString method in the object class.
So why in the example of before I don't see the reference but directly the number?
by logic, the rules of the polymorphism says that: if u have a "child" object in a "father" variable, this object, inside, remanis the same but he is used like an istance of object, so he can just uses the class object and so just the method of object, so is really strange that I don't see the reference but directly the number.
I hope you understand what I mean.
Your last paragraph where you explain your reasoning is slightly incorrect.
so why in the example of before i don't see the reference but directly
the number? by logic, the rules of the polymorphism says that: if u
have a "child" object in a "father" variable, this object, inside,
remanis the same but he is used like an istance of object, so he can
just uses the class object and so just the method of object, so is
really strange that i don't see the reference but directly the number.
The beginning is correct, but the part I bolded is an incorrect conclusion you drew from it.
You are correct that with polymorphism, the object truly remains whatever type it is, but the reference type (the type of the variable) defines what you can do with it. However, the reference type does not describe what the object does
That is the intent behind polymorphism. It is an abstraction to define what can be done separately from how it works. For example, if you have this example:
public class Vehicle {
public int getWheelCount() {
return 1;
}
}
public class Car extends Parent {
public int getWheelCount() {
return 4;
}
public void blowHorn() {
System.out.println("Honk honk!");
}
}
public class Bicycle extends Parent {
public int getWheelCount() {
return 2;
}
}
Car car = new Car();
car.getWheelCount(); // 4
car.blowHorn(); //"Honk honk!"
Vehicle v = new Car();
v.getWheelCount() // 4
v.blowHorn(); // COMPILE ERROR HERE! Unknown method
Bicycle b = new Bicycle();
b.getWheelCount(); // 2
Vehicle v = new Bicycle();
v.getWheelCount(); // 2
What you can conclude from this is that when over-riding a method in a sub-class, the child version is always called. A car is always a car whether you are referring to it as a vehicle or as a car. But by referring to it as a vehicle, you are limited to invoking methods which are defined on all vehicles.
To tie it to the example, all Vehicle objects have a wheel size, therefore getWheelCount() is always callable whether it's Vehicle.getWheelCount() or Car.getWheelCount(). However, Car.getWheelCount() is what executes because Car over-rides it.
If the reference type is Vehicle, you cannot call blowHorn() because that method is only available on Car.
Going back to your example, an Integer is an Integer.
Object i = new Integer(5);
i.toString(); // 5
This prints 5 because i is an integer. The Integer class over-rides toString. The reference type (the type you are referring to the object as) only determines which methods you can call, but not which parent/child class's version of the method is called.
By defining it as Object this means you will only have access to methods that are defined in the Object class.
This includes toString().
So when you instantiate new Player() you still only have access to the methods from Object, but if you override this (like Integer.toString() does), you will still have the output as defined in the instantiated class.
PS: Father -> Parent
This is how the concept of overriding methods works: once an object somewhere in the inheritance hierarchy provides an implementation, it is this implementation that is going to be called, unless it is overridden by another class further down the inheritance hierarchy.
Since java.lang.Integer provides an override of toString(), this override is called instead of the implementation provided by the java.lang.Object.
There is no difference between System.out.println(myIntObj) and System.out.println(myIntObj.toString()), because println will call toString internally on all objects which it does not know how to print.
The reason your Player class behaves differently is that it does not override toString(). If it did, you would see its results printed. With no override, however, the default implementation provided by java.lang.Object is called, which prints some generic object info.
Object myIntObj = new Integer(5);
Here you're creating a new Integer instance, not a bare Object instance. The fact that you're assigning it to an Object reference doesn't transform it into a bare Object. It's still an Integer, but you can reference it as an Object because it extends Object. So when you call myIntObj.toString(), you're calling that instance's toString() method. That instance turns out to be an Integer instance. And so Integer.toString() is called.
Object currentPlayer = new Player();
In this case the same rules apply when calling currentPlayer.toString(): you're actually calling Player.toString(). If Player class does not override toString(), then first ascending parent class toString() implementation is called. If Player directly extends Object, then Object.toString() is called, but if for example Player extends Human and Human extends Object, then Human.toString() is going to be called if it exists. If not, then Object.toString().
Consider this case where Employee has a subclass Manager that has a method getDetails() overridden,
Employee e=new Employee();
Employee m=new Manager();
If you invoke e.getDetails() you will get the behavior associated with Employee.
If you invoke m.getDetails() you will get the behavior associated with Manager.
In general, you get the behavior associated with the object to which the variable refers at runtime. This behavior is often referred to as virtual method invocation.
So the reason why you are getting the behavior associated with Integer when your reference is an object is because you are referring to an Integer object at runtime.

Using reflection - how to get all fields and methods

Using Java reflection:
How can I get all the methods of a given object (private, protected, public etc)
And perhaps create a structural representation of the class
And finally, serialize the object into String or byte array
Does this idea look sound? or this won't get me anywhere?
What I'm trying to achieve is to be able to:
Serialize any java.lang.Object into byte array or String
Class / Objects that don't implement Serializable will be thrown into my application for serialization
Sounds complicated. Just use XStream.
String xml = new XStream().toXML(whatever);
Question 1: How to get all methods of a class.
getDeclaredMethods will provide you with access to all of the methods on a class.
Returns an array of Method objects reflecting all the methods declared
by the class or interface represented by this Class object. This
includes public, protected, default (package) access, and private
methods, but excludes inherited methods.
Example: Method[] methods = Integer.class.getDeclaredMethods();
Question 2: Create a Structural Representation of a Class
I'm not sure why you would need to do this since it already exists. You can always retrieve an object's class, which provides you with its structure.
To get all methods and fields for a class, use getDeclaredMethods and getDeclaredFields. I'm not sure if you can use it to re-compose a non serializable class though, and I'm not sure I would either. But maybe you can find some ideas here: How to serialize a non-serializable in Java?
Class.getDeclaredMethods() and Class.getDeclaredFields() return methods and fields with any visibility declared in current class only. These methods do not return inherited stuff. To do this you have to iterate over the class hierarchy and call these methods for each super class, i.e.:
List<Method> methods = new ArrayList<>();
List<Field> fields = new ArrayList<>();
for (Class c = clazz; c != null; c = c.getSuperClass()) {
methods.add(c.getDeclaredMethods());
fields.add(c.getDeclaredFields());
}

Return type ambiguity

Consider the following code from The Java Programming Language book
public class MyClass extends HerClass implements Cloneable {
public MyClass clone()
throws CloneNotSupportedException {
return (MyClass) super.clone();
}
// ...
}
When the overiding clone() function already species the return type as MyClass then what is the requirement of specifying it again in the return statement ?
Also since the clone of Myclass's super class object is being created (cause clone() is being called wrt superclass), how can it be of Myclass type?
Thanks in advance
Because clone() returns an object of class Object, and you must cast it to the correct type. But you know it is an object of type MyClass, so that cast is correct.
In theory you're right: as you have to specify the type of function return values the compiler could try and perform the correction automatically. On the other hand requiring an explicit conversion helps identify possible errors.
Unless you have specific requirements the clone() method of the Object class already does the right thing, i.e. it creates an object of the correct class and copies all the non-static attributes in the cloned object. However it cannot return it as a derived type because at compile time that type is not known to the Object class itself.
It is true that the clone() method could have been provided automatically for all classes, but sometimes you don't want it to be available and at other times you want to override the default behaviour; for instance you might have an id attribute in your class that you want to be different for each instance of your class even when cloned. Having to override the clone() method gives you a place where you can implement such functionality.
This is because the clone() method in Object returns an Object. However you can return your subclass in clone() because it extends an Object. If the method in MyClass looked like this
public Object clone()
Then it would still be a valid cloneable object and it would work. You wouldn't need to cast anything. The interface, Cloneable is just a marker interface, which means it doesn't actually have any methods.
Your easy question first: why is super.clone() cast to MyClass? That's because the declaration of HerClass.clone() specified a returned value of HerClass, so you must cast it to the right type.
Now, for the more difficult question: how can super.clone() actually return an instance of MyClass? I actually had a hard time finding the answer, but I did somewhat find an answer in Effective Java by Joshua Bloch. There is still some "magic" in the background of Object.clone() that I don't quite understand.
Item 11 from the book:
In practice, programmers assume that if they extend a class and invoke
super.clone from the subclass, the returned object will be an instance
of the subclass. The only way a superclass can provide this
functionality is to return an object obtained by calling super.clone.
If a clone method returns an object created by a constructor, it will
have the wrong class. Therefore, if you override the clone method in a
nonfinal class, you should return an object obtained by invoking
super.clone. If all of a class’s superclasses obey this rule, then
invoking super.clone will eventually invoke Object’s clone method,
creating an instance of the right class.
I originally tried to answer your question by writing a program without knowing you always had to call super.clone(). My homemade clone method for HerClass was returning a new instance of HerClass generated from a constructor (new HerClass()). The code compiled, but it failed at execution when I was trying to cast (MyClass) super.clone(). Only methods that are chained down from Object.clone() can return a value that is an instance of one of their subtype.
Note that if HerClass.clone() is not explicitly implemented, by default it simply returns Object.clone(). The default method has protected access, but since you are calling it from a subclass, it's not a problem.

is there any other way of creating an object without using "new" keyword in java [duplicate]

Had a conversation with a coworker the other day about this.
There's the obvious using a constructor, but what are the other ways there?
There are four different ways to create objects in java:
A. Using new keyword
This is the most common way to create an object in java. Almost 99% of objects are created in this way.
MyObject object = new MyObject();
B. Using Class.forName()
If we know the name of the class & if it has a public default constructor we can create an object in this way.
MyObject object = (MyObject) Class.forName("subin.rnd.MyObject").newInstance();
C. Using clone()
The clone() can be used to create a copy of an existing object.
MyObject anotherObject = new MyObject();
MyObject object = (MyObject) anotherObject.clone();
D. Using object deserialization
Object deserialization is nothing but creating an object from its serialized form.
ObjectInputStream inStream = new ObjectInputStream(anInputStream );
MyObject object = (MyObject) inStream.readObject();
You can read them from here.
There are various ways:
Through Class.newInstance.
Through Constructor.newInstance.
Through deserialisation (uses the no-args constructor of the most derived non-serialisable base class).
Through Object.clone (does not call a constructor).
Through JNI (should call a constructor).
Through any other method that calls a new for you.
I guess you could describe class loading as creating new objects (such as interned Strings).
A literal array as part of the initialisation in a declaration (no constructor for arrays).
The array in a "varargs" (...) method call (no constructor for arrays).
Non-compile time constant string concatenation (happens to produce at least four objects, on a typical implementation).
Causing an exception to be created and thrown by the runtime. For instance throw null; or "".toCharArray()[0].
Oh, and boxing of primitives (unless cached), of course.
JDK8 should have lambdas (essentially concise anonymous inner classes), which are implicitly converted to objects.
For completeness (and Paŭlo Ebermann), there's some syntax with the new keyword as well.
Within the Java language, the only way to create an object is by calling its constructor, be it explicitly or implicitly. Using reflection results in a call to the constructor method, deserialization uses reflection to call the constructor, factory methods wrap the call to the constructor to abstract the actual construction and cloning is similarly a wrapped constructor call.
Yes, you can create objects using reflection. For example, String.class.newInstance() will give you a new empty String object.
There are five different ways to create an object in Java,
1. Using new keyword → constructor get called
Employee emp1 = new Employee();
2. Using newInstance() method of Class → constructor get called
Employee emp2 = (Employee) Class.forName("org.programming.mitra.exercises.Employee")
.newInstance();
It can also be written as
Employee emp2 = Employee.class.newInstance();
3. Using newInstance() method of Constructor → constructor get called
Constructor<Employee> constructor = Employee.class.getConstructor();
Employee emp3 = constructor.newInstance();
4. Using clone() method → no constructor call
Employee emp4 = (Employee) emp3.clone();
5. Using deserialization → no constructor call
ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
Employee emp5 = (Employee) in.readObject();
First three methods new keyword and both newInstance() include a constructor call but later two clone and deserialization methods create objects without calling the constructor.
All above methods have different bytecode associated with them, Read Different ways to create objects in Java with Example for examples and more detailed description e.g. bytecode conversion of all these methods.
However one can argue that creating an array or string object is also a way of creating the object but these things are more specific to some classes only and handled directly by JVM, while we can create an object of any class by using these 5 ways.
Cloning and deserialization.
Also you can use
Object myObj = Class.forName("your.cClass").newInstance();
This should be noticed if you are new to java, every object has inherited from Object
protected native Object clone() throws CloneNotSupportedException;
Also, you can de-serialize data into an object. This doesn't go through the class Constructor !
UPDATED : Thanks Tom for pointing that out in your comment ! And Michael also experimented.
It goes through the constructor of the most derived non-serializable superclass.
And when that class has no no-args constructor, a InvalidClassException is thrown upon de-serialization.
Please see Tom's answer for a complete treatment of all cases ;-)
is there any other way of creating an object without using "new" keyword in java
There is a type of object, which can't be constructed by normal instance creation mechanisms (calling constructors): Arrays. Arrays are created with
A[] array = new A[len];
or
A[] array = new A[] { value0, value1, value2 };
As Sean said in a comment, this is syntactically similar to a constructor call and internally it is not much more than allocation and zero-initializing (or initializing with explicit content, in the second case) a memory block, with some header to indicate the type and the length.
When passing arguments to a varargs-method, an array is there created (and filled) implicitly, too.
A fourth way would be
A[] array = (A[]) Array.newInstance(A.class, len);
Of course, cloning and deserializing works here, too.
There are many methods in the Standard API which create arrays, but they all in fact are using one (or more) of these ways.
Other ways if we are being exhaustive.
On the Oracle JVM is Unsafe.allocateInstance() which creates an instance without calling a constructor.
Using byte code manipulation you can add code to anewarray, multianewarray, newarray or new. These can be added using libraries such as ASM or BCEL. A version of bcel is shipped with Oracle's Java. Again this doesn't call a constructor, but you can call a constructor as a seperate call.
Reflection:
someClass.newInstance();
Reflection will also do the job for you.
SomeClass anObj = SomeClass.class.newInstance();
is another way to create a new instance of a class. In this case, you will also need to handle the exceptions that might get thrown.
using the new operator (thus invoking a constructor)
using reflection clazz.newInstance() (which again invokes the constructor). Or by clazz.getConstructor(..).newInstance(..) (again using a constructor, but you can thus choose which one)
To summarize the answer - one main way - by invoking the constructor of the object's class.
Update: Another answer listed two ways that do not involve using a constructor - deseralization and cloning.
There are FIVE different ways to create objects in Java:
1. Using `new` keyword:
This is the most common way to create an object in Java. Almost 99% of objects are created in this way.
MyObject object = new MyObject();//normal way
2. By Using Factory Method:
ClassName ObgRef=ClassName.FactoryMethod();
Example:
RunTime rt=Runtime.getRunTime();//Static Factory Method
3. By Using Cloning Concept:
By using clone(), the clone() can be used to create a copy of an existing object.
MyObjectName anotherObject = new MyObjectName();
MyObjectName object = anotherObjectName.clone();//cloning Object
4. Using `Class.forName()`:
If we know the name of the class & if it has a public default constructor we can create an object in this way.
MyObjectName object = (MyObjectNmae) Class.forName("PackageName.ClassName").newInstance();
Example:
String st=(String)Class.forName("java.lang.String").newInstance();
5. Using object deserialization:
Object deserialization is nothing but creating an object from its serialized form.
ObjectInputStreamName inStream = new ObjectInputStreamName(anInputStream );
MyObjectName object = (MyObjectNmae) inStream.readObject();
You can also clone existing object (if it implements Cloneable).
Foo fooClone = fooOriginal.clone ();
Method 1
Using new keyword. This is the most common way to create an object in java. Almost 99% of objects are created in this way.
Employee object = new Employee();
Method 2
Using Class.forName(). Class.forName() gives you the class object, which is useful for reflection. The methods that this object has are defined by Java, not by the programmer writing the class. They are the same for every class. Calling newInstance() on that gives you an instance of that class (i.e. callingClass.forName("ExampleClass").newInstance() it is equivalent to calling new ExampleClass()), on which you can call the methods that the class defines, access the visible fields etc.
Employee object2 = (Employee) Class.forName(NewEmployee).newInstance();
Class.forName() will always use the ClassLoader of the caller, whereas ClassLoader.loadClass() can specify a different ClassLoader. I believe that Class.forName initializes the loaded class as well, whereas the ClassLoader.loadClass() approach doesn’t do that right away (it’s not initialized until it’s used for the first time).
Another must read:
Java: Thread State Introduction with Example
Simple Java Enum Example
Method 3
Using clone(). The clone() can be used to create a copy of an existing object.
Employee secondObject = new Employee();
Employee object3 = (Employee) secondObject.clone();
Method 4
Using newInstance() method
Object object4 = Employee.class.getClassLoader().loadClass(NewEmployee).newInstance();
Method 5
Using Object Deserialization. Object Deserialization is nothing but creating an object from its serialized form.
// Create Object5
// create a new file with an ObjectOutputStream
FileOutputStream out = new FileOutputStream("");
ObjectOutputStream oout = new ObjectOutputStream(out);
// write something in the file
oout.writeObject(object3);
oout.flush();
// create an ObjectInputStream for the file we created before
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("crunchify.txt"));
Employee object5 = (Employee) ois.readObject();
From an API user perspective, another alternative to constructors are static factory methods (like BigInteger.valueOf()), though for the API author (and technically "for real") the objects are still created using a constructor.
Depends exactly what you mean by create but some other ones are:
Clone method
Deserialization
Reflection (Class.newInstance())
Reflection (Constructor object)
there is also ClassLoader.loadClass(string) but this is not often used.
and if you want to be a total lawyer about it, arrays are technically objects because of an array's .length property. so initializing an array creates an object.
We can create an objects in 5 ways:
by new operator
by reflection (e.g. Class.forName() followed by Class.newInstance())
by factory method
by cloning
by reflection api
We can also create the object in this way:-
String s ="Hello";
Nobody has discuss it.

Categories

Resources