How can I create an object of this class? - java

In class B, how can I create an object of class A other than the process of object creation (i.e. without creating an object having null)?
class A
{
public int one;
A(A a)
{
a.one=1;
}
}
class B
{
public static void main(String...args)
{
//now how to create an object of class A over here.
}
}

To construct an object of type A you need to pass to the constructor either a reference to another object of type A, or else the null reference. So you have only two options:
A a1 = new A(null);
A a2 = new A(a1);
The first time you create an object of type A you must use the null reference because you don't have any other objects of type A.
Update
After you changed your question, I don't think it's possible to construct an object of type A.

If I understand your question correctly, you want to create an object a without having to pass it a pre-existing object of the same type.
To do so you have to add a constructor to class A that does not take a parameter of type A or modify the existing one:
class A
{
A() {
// Constructor logic.
}
A(A a) {
// Constructor logic when passing an existing object of the same type, perhaps to create a clone.
}
}
If for some reason you can't modify class A, you'll have to follow Mark Byers' answer and pass a null reference to the constructor.
Update
With the update to your code, this problem (or thought experiment) is unsolvable: class A can not be instantiated as written.

You cannot normally do this in Java.
However, it's possible with heavy cheating. Don't do this in production code. But for the sake of argument:
1) With Mockito (But won't work with a security manager):
import org.mockito.Mockito;
class B {
public static void main(String... args) {
A mockedA = Mockito.mock(A.class);
A realA = new A(mockedA);
System.out.println(realA);
}
}
2) Here's another way to do it overriding finalize().

Only way to create A object is by giving him other A object in constructor, but that other A object also needs another A object in constructor. This will stop only when you put null reference in constructor.
Edit
My answer was based on your previous version of code. Now you can't create object because you can't put null in constructor (null desn't have one field). If you want to create A object, you have to do test for null in constructor like if (a!=null){ a.one=1;} and pass null or already created A object in constructor.

If A is sealed (not editable) you could only extend that class and give the one a default constructor to pass it into a new instance of A. There is no other solution without modifying the source code of A.

You can not instantiate A in your example. It is a chicken and egg problem. You need an instance of A to create an instance of A, but you can not create an instance of A without having an instance of A.
So, without changes to A (be it either adding a 'null' check or adding a default constructor) you can not create an instance of A in this scenario.

Related

Can we call method using the reference of the class

I just started to learn java and i found out that, to call a method of normal class we need object but for static class we do not need any object to call we can use class reference to do that. But while coding I came across some code which really confused me. The code is.
public class MyInterceptor extends AbstractInterceptor {
#Override
public String intercept(ActionInvocation actionInvocation) throws Exception {
String result = actionInvocation.invoke();
Here my doubt is in the 3rd line we have a reference actionInvocation for a class ActionInvocation and we have not used any new keyword and now check the 4th line we used actionInvocation to access the methos invoke(). How is this possible without using new keyword? I also checked that ActionInvocation is abstract interface.
The new keyword is only used to construct an object. Once it has been created, it can be passed around between methods, other classes, and other places where an object may be stored or transmitted.
You are making a method of MyInterceptor that accepts an ActionInvocation object. This object can either be passed as null, or would have been created elsewhere. You can perform a not-null check (via actionInvocation!=null) to ensure that you're indeed passed an object.
Also, you should remember that you yourself can create objects without using new in your class. There are such ways called factories, where you call a static method such as ByteBuffer.allocateDirect( and that internally uses the new keyword to create an instance of ByteBuffer.
That's perfectly fine code. The ActionInvocation instance is created elsewhere and passed to the intercept(...) method. In fact ActionInvocation actionInvocation is just a reference to an object of a class that extends or implements ActionInvocation, i.e. the actual class of that object could be a subclass/implementation of ActionInvocation.
The concept behind this is called polymorphism: an object of a certain class is also an object of its superclasses and/or might be referenced through implemented interfaces.
An example:
Suppose you have an object like this:
Integer someInt = new Integer(1);
You could pass someInt as a parameter to the following methods:
void doSomething( Integer i) { ... }
void doSomething( Number n) { ... }} //because Integer extends Number
void doSomething( Object o) { ... } //because all objects extend Object
void doSomething( Comparable c) { ...} //because Integer implements Comparable (note that I left out generics here for simplicity)
Note that you could also pass null as an object, as the others already stated, but in your case you should be safe to assume that actionInvocation is never null (this is most likely documented in the API docs).
actionInvocation is initialized(with new) in another place of the program.
You will need a little more understanding of how inheritance and interfaces work to understand this. But the overall logic here is that the method is assuming that object of type ActionInvocation is already instantiated, which might not be the case. Anyways you can look at the calling code for method intercept where an object being passed here must have been instantiated by using new.
By the way ActionInvocation is interface so any "subclass" of this interface can call this method. Have a look at the inheritance terminology to understand what that means.
public String intercept(ActionInvocation actionInvocation)
To call this method any where in your program,
you need to have a created object of type ActionInvocation, then and then only you can call that method.
Once you pass to that,The story inside is usual.
In short,
That object created before calling this method and coming here to do the stuff.

Why do we need Downcasting really? [duplicate]

This question already has answers here:
Upcasting and Downcasting in java
(8 answers)
Closed 9 years ago.
I am trying to figure out why do I need Downcasting. I reread my notes from collage and found the below example.
class Student {...}
class Graduate exteds Student {
getResearchTopic(){...} // this method only exists in Graduate class.
}
We have a ref to Student class and want to access to getResearchTopic method;
Student s1 = new Graduate();
if(s1 instanceof Graduate){
((Graduate)s1).getResearchTopic();
}
Great example for Downcasting hah? My question is Why not declare s1 as a Graduate in the first place? Is there a real life example where I will have to downcast instead of using an instance of actual class?
Well, you could have declared the reference s1 to be of type Graduate. The main benefit you get by declaring the reference of super type, is the power of polymorphism.
With a super type reference, pointing to a sub class object, you can bind the same reference to multiple sub class objects. And the actual method invoked will be decided at runtime, based on what object is being pointed to. But, the main condition for this is, that method should also be defined in the subclass, else the compiler will fail to find the method declaration.
Here, you were forced to downcast, because you haven't defined the method in the super class. As compiler cannot see the definition of that method in Student class. It has no idea about what the actual object s1 points to. Remember, compiler only checks the reference type to find the meethod declaration.
In general, whenever you see yourself downcasting to a subclass in your code, it is almost always a sign a something wrong (there are some exceptions though). And you should modify your classes.
Let's see what benefit you get by using a super class reference instead of a subclass reference:
For e.g: Suppose you have another sub class of Student as:
class Phd extends Student {
getResearchTopic(){...}
}
and you also provide a definition (a default one) in Student class:
class Student {
getResearchTopic(){...}
}
Now, you create a following two objects, both being pointed to by Student reference:
Student student = new Phd();
student.getResearchTopic(); // Calls Phd class method
student = new Graduate();
student.getResearchTopic(); // Calls Graduate class method
So, with only a single reference, you get to access methods specific to subclasses.
One major implementation of this feature you can see in factory method pattern, where a single static method returns an object of different sub classes based on some condition:
public static Student getInstance(String type) {
if (type.equals("graduate"))
return new Graduate();
else if (type.equals("phd"))
return new Phd();
}
So, you can see that the same method returns an object of different subclasses.
All of the above stuffs you can do just because of one concept:
A Super class reference can refer to any sub class objects, but not vice-versa.
Say you have a method that takes a Student as a parameter. Most of the things it does are generic for all students. But if it is a Graduate there might be something else it does as well. In that case you would need to determine if the Student passed in was actually a Graduate and do some special logic in that instance.
Maybe something like this:
class StudentDAO {
public void SaveStudent(Student s) {
// Do something to save the student data to a database.
if ( s instanceof Graduate ) {
// Save their research topic too.
}
}
}
Note that doing that kind of thing is usually a poor programming practice, but sometimes it makes sense.
When you deserialize an object using the default Java deserializer, you use this code (and you use analogous code when using another deserializer, e.g. the Jackson JSON deserializer)
ObjectInputStream ois = new ObjectInputStream(in);
Object obj = ois.readObject();
You then need to cast obj to its actual type, because readObject() will always return a plain old Object - the method can't statically verify what sort of object is being read
In cases where you want to use polymorphism, it would be nice to work with Student objects, and then "downcast" to use methods specific to Graduate objects.
In general, if you have a method that works with Student objects, that method don't really know at compile-time what specific type of Student objects are passed in. Thus, at run-time, the method should check for the specific type and process accordingly.
Downcasting does help when you're trying to make generic methods. For example, I often see code that parses an XML String into an Object. The Object can then be downcast into the specific Object that you (as the coder) know it represents.
private static XStream xstream = new XStream(new DomDriver());
static {
xstream.processAnnotations(MyFirstClass.class);
xstream.processAnnotations(MySecondClass.class);
// ...
}
public static Object fromXML(String xml) {
return xstream.fromXML(xml);
}
This lets me make a very generic method which does what I want it to do in all cases. Then, when I call it, I can simply downcast the Object into what I know it's going to be. It prevents me from having to make a separate parse method for every object type and improves the readability of my code.
MyFirstClass parsedObject = (MyFirstClass) MyXMLTransformer.fromXML(xml);

Access super field from subclass object

This may be a strange question, but I don't understand how have I managed to get this to work. My intention was to access the super's field from an object that overrides the field. First, what did work (1):
class Foo {
protected int i = 0;
}
public class Bar extends Foo {
int i = 1;
Foo f() {
return this;
}
public static void main (String[] args) {
Bar b = new Bar();
System.out.println(b.i);
System.out.println(b.f().i);
}
}
I first tried to use something like (2):
System.out.println(b.super.i);
which didn't work. I then tried to use (3):
Foo f() {
return super;
}
and that didn't work either.
So, referring to the numbered parts above:
Why does return this cast to Foo return a reference to the b.super object?
In main, I would have thought b.super would be the reference to the instantiated object "b" 's super reference. Is there any way to access the reference to the super object from the containing object? Maybe something from reflection, but I don't want access to the .class object (b.getClass().getSuper()), but rather the instantiated Foo contained within b.
Why does return.super not return a reference to the b.super object?
My intention was to access the super's field from an object that overrides the field.
You are not "overriding" the field. You are creating a second, unrelated field with the same name. The resulting name clash is the direct cause of your difficulty.
If the two fields are unrelated, give them different names.
If, on the other hand, you are trying to achieve polymorphic behaviour, turn them into methods:
class Foo {
protected int get_i() { return 0; }
}
public class Bar extends Foo {
#Override
protected int get_i() { return 1; }
}
since fields can not be overridden, they remains hidden when you use the same name in sub classes. Thats why you can not access those super class fields if you have redefined field in subclasses.
if you want to access those, you should provide getters/setters in superclass.
Because fields are not accessed in a polymorphic, dynamic way. The declared type of the object returned is Foo, so Foo's field is accessed. Fields can't be overridden. Defining i in the subclass creates another field that happens to have the same name as the one in the superclass, and thus hides it.
There's no way. You should amost never access fields of an object directly. Use methods instead.
Because that's invalid Java code. return super makes no sense. super is not a different object. super and this are the same object.
You don't need reflection, you need to define setter and getter methods in your superclass.
Your questions answered:
Why does return.this cast to Foo return a reference to the b.super object?
It does not, exactly. It returns a reference to 'this' which is an instance of Bar and also of Foo, because Bar extends Foo.
In main, I would have thought b.super would be the reference to the instantiated object "b" 's super reference. Is there any way to access the reference to the super object from the containing object? Maybe something from reflection, but I don't want access to the .class object (b.getClass().getSuper()), but rather the instantiated Foo contained within b.
b and b.super are one and the same. You can access Foo protected fields from Bar code without a problem
Why does return.super not return a reference to the b.super object?
Again, b and b.super are the same instance.

How to choose which constructor to use and what class does the Class<?> type belongs to

I have a class in which i have intialized hashmap in static block. Passing the key, I have retrived the value which is a class. In order to create object for this class. I have used the constructor class to get the constructor and passed arguments and created object.
I have two class in hashmap. To create objectfor EchoExpression I need to pass two arguments and for OutExpression class i need to pass only one argument(String).
Based on the class returned by the key I need to execute which constructor to get and implement, whether the constructor with one argument or two argument.
In EchoExpression, the constructor contains two arguments.
eg:
JXPathExpression check = new JXPathExpression(String expression, Class<?> type)
String belongs to String.class but what class does the Class type argument belongs too? so that i can use it in getting the constructor
public class ExampleFactory {
private static HashMap<String,Class<?>> hmap = new HashMap<String,Class<?>>();
static
{
hmap.put("echo", EchoExpression.class);
hmap.put("Out", OutExpression.class);
}
public void getExpo(String key,String expression)
{
Class aClass =map.get(key);
//Constructor implementation for OutExpression where only one argument string is passed
Constructor constructor = aClass.getConstructor(new Class[]{String.class});
Object object= constructor.newInstance(expression);
//Need constructor for passing two arguments string and class<?> for EchoExpression
return null;
}
}
For such a thing you should in all cases try to have unified constructor parameters or a way to store the parameters per class.
Now for your questions. Class<?> is a reference to a unknown class. Basically to any class. When using it its more or less equal to Class<Object> because all classes got Object as parent.
For using constructors with multiple arguments you first need to fetch the fitting constructor. At this point its already possible to fetch errors that happen in case the class does not support instances with this configuration of arguments.
Fetching the constructor works this way:
aClass.getConstructor(new Class[]{String.class, Object.class, ...});
This works with as many argument types as you like. Creating the new instance of the class then works this way:
constructor.newInstance(theString, theObject, ...);
The function newInstanace is implemented as many arguments as needed. So depending on how many arguments the constructor that was requested requires the newInstance function will be able to work with it.
For all what you intend... maybe a proposal: Maybe its a option not to load the new objects using reflection but rather by storing instances of those objects and returning copies of the objects created using copy constructors or the clone method. In many cases this is less difficult to get running.
Maybe what you are looking for is Class.class like in:
Constructor constructor = aClass.getConstructor(new Class[]{String.class, Class.class});

Is there absolutely NO way in Java to pass the object itself to a method so it actually gets changed?

class MetaData {
public String version;
public String compression;
}
I make a MetaData object, pass it into a method, and fill the version and compression fields from within the method. And I want these changes to exist outside of the lifetime of the method. In C++ I think I added a & or something to pass the object itself and not a copy of it to the method. Is there ANYWAY to do the same in Java?
This will always happen in Java. It's just the way Java works. When you pass a "MetaData" object to a method, a reference to that object is passed and any modifications made to its "version" and "compression" fields should be seen everywhere.
Check out this article for a really in-depth explanation:
http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
Java has pass by value semantics. This does not mean that objects are passed by value to methods. Rather, it means that references to objects are passed by value to methods.
So in this scenario, when you create a MetaData object, and pass it to a method where in the fields are populated, the reference to the object is passed to that method. Once the method returns, you can examine the object reference in the caller to confirm that its fields have been set.
By the way, this is a bad practice in OOP, if you are sending a MetaData object to another class for setting the state of the object. Objects themselves should be in charge of their state.
This is the default behaviour in Java.
class Example {
public static void doit(MetaData data) {
data.compression = "Testing"
}
public static void main(String[] args) {
MetaData data = new MetaData();
doit(data);
System.out.println(data.compression);
}
}
All mutable objects you pass to methods can be changed, and the original will change. The problem is that String cannot be changed--it is immutable.
Pass an object that can be changed.
If you want to change "version", then give your class "MetaData" a .setVersion() method and pass "MetaData" to your method. Your method would call metaData.setVersion("I'm NEW"); and everyone will be happy.
public void willWorkFine (Metadata metaData) {
metaData.setVersion("Changed!");
}
What you can't do is pass "version" to a method expecting a String and re-assign it:
public void wontWork(String changeMe) {
changeMe="not changed!";
}
Since changeMe is just a local reference to the original "version" object, reassigning your local reference to point to a different object has no effect on the outside program.

Categories

Resources