I have created an instance of an object in one of my classes for a Java program. How can I pass the same instance of that object to another class?
Would I need to do something like creating some type of a getter method in the original class to pass the object through to the other class?
To "pass" it you need a method or a constructor in the other class that can accept it:
public class Other {
// either
public Other(MyClass obj) {
// do something with obj
}
// or
public void method(MyClass obj) {
// do something with obj
}
}
Then call the constructor/method:
MyClass x = new MyClass();
Other other = new Other();
other.method(x);
There are many ways to pass the reference for one object to another object. The simplest and most common ways are:
as a constructor parameter,
as a parameter of a setter method; e.g. setFoo(Foo foo) to set the "foo" attribute, or
as an "add" method in the object being passed is going to be added to a collection; e.g. addFoo(Foo foo).
Then there are a variety of more complicated patterns where objects are passed using publish/subscribe, call-backs, futures, and so on.
Finally there are some tricks that can be used to "smuggle" objects across abstraction boundaries ... which are generally a bad idea.
You can pass the object via the constructor of the other class.
Simple Example:
Class A{
}
Class B{
A a;
public B(A obj){
this.a=obj
}
}
Let's assume you want to pass an object of class A to class B. Now you have created the object like this:
A object = new A ();
And now in your B class, you can write a method to accept a A object. It should be public and you can make it static if you like.
If you want to pass object to B, you must want to do something with it, right? So you should name your method accordingly. You probably want to assign a field of type A (Let's call this fieldA) in B. (or maybe that isn't what you want, but I'll use this for the example)
Let's look at the method:
public void setFieldA (A a) {
fieldA = a;
}
You can call this method as follows:
anObjectOfClassB.setFieldA (object);
Of course you don't need anObjectOfClassB if it is static.
Related
Lets say I have Object X and Object B. X is an object of a random class, which in turn creates B, and passes itself on to be stored as a variable in object B.
Now object B, wants to run a method in object X, without knowing what class it is.
Is it possible to call a method in any object, and if a method with that name exist, it runs, and if not, it doesn't. I assume some try/catch can work around that part.
But lets say i have something like this:
public class ObjectB {
public Object parentX;
public ObjectB(Object x) {
parentX = x;
}
public void anyMethod() {
x.runMyMethod();
}
}
In another program I worked with, this was possible with interfaces, and therefore have an idea that it is possible with Java too. However, i cant seem to find the way to set this up. So if the above was the case, how would it be set up, such that ObjectB can call the method on all the classes in my program if that was what i wanted?
Yes its definitely possible.
Define interface MyIntf, and your Class X implements it. now in Class B you can assign the object of Class X (or any class that implements MyIntf) to parent which of type MyIntf the you can invoke method with that parent
interface MyIntf
{
void runMyMethod()
}
public class ObjectX implements MyIntf {
void runMyMethod()
{
}
}
public class ObjectB {
public MyIntf parentX;
public ObjectB(MyIntf x) {
parentX = x;
}
public void anyMethod() {
parentX.runMyMethod();
}
}
Now object B, wants to run a method in object X, without knowing what class it is.
Simply doesn't make sense. In order to invoke a method, you need to know its name and the expected parameters. In that sense, class B needs some knowledge. Thus, you would/could do something like
if (parentX instanceof ClassA) {
( (ClassA) parentX ) . someAMethod(bla, blub);
}
if (parentX instanceof InterfaceC) {
( (InterfaceC) parentX ) . someCMethod(bla, blub);
}
In that sense: you might use an interface here; but classes work as well. The key thing is: you need a certain piece of information; otherwise you are simply stuck.
The only other alternative is to look into reflection - then you would not need to know the specific type; as you can inspect parentX to find out which methods could be called on that object. But reflection is A) an advanced concept and b) intricate in its usage.
If you look at the end of this documentation, it tells you about casting. Casting allows the program to assume the object is of a type and attempt to call a method within it.
public void anyMethod() {
((MethodParentObject) this.x).runMyMethod();
}
I am naive to java programming.
How to access an object created in one class into another class.
Class A
{
Obj
}
Class B
{
//Here i want to use Obj
A.Obj
}
For the above i declare Obj as public static, but when i use it in Class B as A.Obj, it is returning a syntax error saying
"Cannot make a static reference to the non-static field A.Obj".
Am i missing something here? Are there any other ways?
Yes you cant access without having an instance of A. You could do something like:
System.out.println(new A().Obj);//or define Obj as static in A class.
Note - You should encapsulate your Obj and access it via getter method.
You should use provide a get method or use that object in static method as well. for your information static will not garbage collected unless the execution gets stopped for more about your answer use this answer's reference
You need first to declare your Obj in class A as static
class A {
static Object object = new Object();
}
Then you can use it
class B {
A.object //in the class cannot be accessed directly
Object x = A.object; //can use it to assign a value
public Object Foo() {
A.object //in a method can be accessed directly
return A.object; //here as expression result
}
}
I have a class that performs a business function and there are multiple methods being called by the entry-point method.
public class Tool
{
public void runTool()
{
methodA();
methodB();
methodC();
printToolSummary();
}
}
Each of these methods method* called perform a specific sub-function and I would like to collect the results/attributes of interest in each of these methods into a summary object. Its not a single value to be returned by these method* methods.
I was thinking of a single object that contains all the attributes of interest, pass this object to each method and let that method set the attribute, but somehow it doesn't sound right to work with a mutable object as there is no way to prevent methodA from updating an attribute it shouldn't, or am I worrying too much?
If you're concerned about the methods touching some part of the object that they shouldn't then the object you're passing into the methods should implement several interfaces with each one only exposing the properties that you want the acting method to touch.
So methodA could expect a class of type A and methodB could expect a class of type B where A and B are interfaces...
Otherwise there's not really anything wrong with your approach and it's fairly common.
How about using a complex object that contains sub-classes for each of your methods. For example:
public class ResultA { // some attributes for Method A }
public class ResultB { // some attributes for Method B }
public class ResultC { // some attributes for Method C }
public class Result {
private ResultA resultA;
private ResultB resultB;
private ResultC resultC;
}
I'm loading a class with following statement:
Class classToLoad = Class.forName("com.somePackage.SomeotherPackage.classname" );
Later i wd use reflection to get the methods of this class. now for invoking the methods with methodname.invoke() function i'd require the object of the loaded class. thus i want to create the object of the loaded class. I try to do it this way:
Object obj = classToLoad.newInstance();
but the problem in this is that this way i don't get the object of the class loaded but i get object of Object class.
Now if i want to call the functions of the loaded class, i do it like:
methodName.invoke(obj);
it throws an exception:
java.lang.IllegalArgumentException: object is not an instance of declaring class
can anybody please help?
Update on the problem:
The problem is that i need the left hand side of the assignment to be of a different class type and that class type will be decided on run time
For the below statement:
Object instance = clazz.newInstance();
"instance" should be of the "clazz" type and not the "Object" class.
How can i achieve this?
It works fine when everything's set up correctly:
import java.lang.reflect.Method;
class Foo {
public Foo() {
}
public void sayHello() {
System.out.println("Hello");
}
}
public class Test {
public static void main (String[] args) throws Exception {
Class<?> clazz = Class.forName("Foo");
Method method = clazz.getMethod("sayHello");
Object instance = clazz.newInstance();
method.invoke(instance); // Prints Hello
}
}
My guess is that the method you've fetched (methodName) wasn't actually fetched from classToLoad.
You can also just cast the return type and invoke the method directly.
public class Foo{
void HelloReflection(){
System.out.println("Hello reflection");
}
public static void main(String[] args){
try{
Foo o = (Foo) Class.forName("Foo").newInstance();
o.HelloReflection();
}catch(Exception e){
e.printStackTrace();
}
}
}
java.lang.IllegalArgumentException: object is not an instance of declaring class
This can be thrown if the method has no arguments and not found in your object's class. Probably You are calling the invoke method on the wrong object or your fetched method is wrong for your object.
The problem is that i need the left hand side of the assignment to be of a different class type and that class type will be decided on run time. ... How can i achieve this?
Use some language other than Java. Java is statically typed, which basically means you're not allowed to do exactly what you just asked how to do. The other answers here correctly show how to invoke a method without knowing the type of an object at compile time, but you'll never be able to set the type of a variable at runtime.
Given two java classes, A and B, where A is usually instantiated via B, such as:
A myA = B.createA();
Can I create a subclass of A (let's call it SubA) and somehow have it be instantiated by the B.createA() method?
(Note that I cannot modify A and B....)
I know that not all instances of A are instances of SubA, thus I cannot do this:
SubA mySubA = B.createA();
Similarly, I cannot cast it like this either:
SubA mySubA = (SubA) (B.createA());
for the same reason -- it will get a ClassCastException.
Am I being dense and forgetting something fundamental, or is there no way to do this?
(Late addition: I'm so sorry, I should have mentioned that A and B have roughly 50 methods each, and all I want to do is add a single property to SubA, along with a getter and a setter. I'd really rather not implement all 50 of A's methods to invoke the corresponding method in the superclass's object.)
It sounds like like what you'd really like is to modify the behavior of both the original A and B. In that case, you could try extending both classes (where the extension of B is purely to specify a slightly different factory method for creating SubAs).
class SubA extends A {
/** This is the one special aspect of SubA justifying a sub-class.
Using double purely as an example. */
private double specialProperty;
public double getSpecialProperty() { return specialProperty; }
public void setSpecialProperty(double newSP) { specialProperty = newSP; }
public SubA() {
super();
// Important differences between SubAs and As go here....
// If there aren't any others, you don't need this constructor.
}
// NOTE: you don't have to do anything else with the other methods of
// A. You just inherit those.
}
class SubB extends B {
// Purely for the purposes of a slightly different factory method
public A createA() {
return new SubA();
}
// Or if you need a static method
// (this is usually instead of the first choice)
public static A createA() {
return new SubA();
}
}
Note that at this point, you could create one of your SubB factory objects and make it look like the original B like so:
B myNewB = new SubB();
A myA = myNewB.createA();
Or, if you're using the static factory instead, it isn't quite as close a match (but it's close).
A myA = SubB.createA();
Now, if you really need to do something with the sub-property, you'll have access to it via the child interface. I.e., if you create the object like so:
SubA mySubA = SubB.createA();
mySubA.setSpecialProperty(3.14);
double special = mySubA.getSpecialProperty();
Edit to discuss "Late addition":
At this point, your SubA object should be exactly what you want. It will inherit the 50 methods from the parent (A) and you can add your additional property to the child, plus the getter and setter. I changed the code above to illustrate what I mean.
This is usually done via a proxy:
class SubA extends A {
private A proxiedClass;
public SubA(A a) {
proxiedClass = a;
}
public int anyMethodInA() {
return proxiedClass.anyMethodInA();
}
}
...
SubA mySubA = new SubA(B.createA());
Doing this manually is rather verbose, so most people use some kind of a AOP library (like AspectJ) to only intercept method calls they are interested in.
You could create a wrapper around it, with SubA having a constructor that takes A as the parameter.
Like this:
SubA mySubA = new SubA(B.createA());
Since all instances of SubA are instances of A, you could then assign it to your existing A variable and override any necessary methods.
A myA = new SubA(B.createA());
I can't think of any other clean way of doing it.
If you are just wanting to add a field to A without object oriented such as changing behaviour, you could add it as an "external field". Use a WeakHashMap to map from instance of A onto the field value (just so long as the field value doesn't directly or indirectly reference A or you'll have an object life time contention issue):
private static final Map<A,FieldType> map =
new java.util.WeakHashMap<A,FieldType>(); // thread-safe from 1.6, IIRC
public static FieldType getField(A a) {
return map.get(a);
}
public static void setField(A a, FieldType value) {
map.set(a, value);
}
Really we should be using WeakIdentityHashMap, but it doesn't exist in the Java library!