Java pass a class to check instance of - java

I want to pass a class to a function. In that function, new instance of other classes are created.
Then, I want to be able to find which object there is an instance of the class I passed:
public void doSomething(Class cls) {
SomeObject obj = new SomeObject();
if (obj instanceof cls) {
// Do amazing things here
}
}
class Person {
// This exists
}
doSomething(Person.class);
The code above doesn't work. I hope I'm clear enough what I'm trying to do.

You want to use https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#isInstance-java.lang.Object-.
if (cls.isInstance(obj)){
...
}

If you want to see if an object is an instance of a class type, you need to call isInstance:
if (cls.isInstance(obj)){
}
Or you can do isAssignableFrom:
if (clas.isAssignableFrom(obj.getClass())) {
}

Related

How to pass a created object to another class Java

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.

Calling a method on Mock object is calling real method instead of mocked implementation

I have my code like below
public process() {
extract();
...
}
private Obj extract() {
Constructor const = new Constructor();
Obj object = const.getOBJMethod("12345","c:/file/a.zip",null);
return object;
}
I am testing the method process using mockito.
and in my test class I have written code as
Constructor mocckConst = mock(Constructor.class);
Obj mockObject = mock(Obj.class);
when(mocckConst .getOBJMethod("12345","c:/file/a.zip",null).thenReturn(mockObject);
But while execution of testcase when extract method is called it is going to the real implementation of getOBJMethod().
Constructor class has another inner class. Does that cause any problem?
Can anybody tell me what is going wrong here and the solution.
I would like to improvise my process method.
public process(String base) {
if("abc".equals(base)) {
---
}
else if("def".equals(base) {
extract();
---
}
}
This way extract() is called only when basis is def. and I don't want to pass constructor object to process() method then are there any solutions?
In the class that you want to test you create a new Constructor object (via Constructor const = new Constructor()), hence, you always use the REAL implementation. You have to inject the Constructor object if you want to have it replaced by a mock object for testing. Injection is also possible via constructor for testing.
private final Constructor const; // remove final, if required
public <ConstructorOfYourClassHere>(Constructor const) {
assert const != null : "const != null"; // use assertions, if you like
this.const = const;
// other constructor code...
}
// your other code here...
public process(String base) {
if("abc".equals(base)) {
// ---
}
else if("def".equals(base) {
extract();
// ---
}
}
private Obj extract() {
Obj object = const.getOBJMethod("12345","c:/file/a.zip",null);
return object;
}
Then you can inject the mock when you create the object under test and call process(). Then your mock implementation will be used.
BTW:
If you're the owner of the code, you might want to change the visibility of the extract method to protected so that you can test the method, too. See here.
Also, you might want to read something about dependency injection in general. Testing with DI is often much easier. You don't have to use a DI-framework, just inject your dependencies via method parameters or via constructor at object creation time.
You can spy the Constructor object if you want to have it testable with a mock.
public class Test{
#spy
Constructor const;
public process() {
extract();
...
}
private Obj extract() {
Obj object = const.getOBJMethod("12345","c:/file/a.zip",null);
return object;
}
}

How to access object not stored in variable

I have this method that I pass a newly created object into
foo(new WebObject());
How do I get access to the WebObject to use in another object? In other words where do newly created objects reference go?
That depends on what you mean - if you mean to say that you want to use it later, after the function call, then you want to do something like
WebObject wObj = new WebObject();
foo (wObj);
WebObject nObj = wObj;
If, however, you mean you want to use the object within the foo(WebObject) method, then what you need to do is, within the function, something more along the lines of
foo (WebObject obj)
{
WebObject local = obj;
}
Store it in a variable!
WebObject whatever = new WebObject();
foo(whatever);
bar(whatever);
as user2357112 posted you can assign new object to a local variable and pass it via few methods
WebObject instance= new WebObject();
foo(instance);
foo2(instance);
System.out.println(instance);
but if you're looking something else, you might assign it to a supporting class
public class WebObjectKeeper{
private static WebObject instance=null;
public static void setWebObject(WebObject obj){
this.instance=obj;
}
public static WebObject getWebObject(){
return instance;
}
}
and then you use it in code like:
public void myMethod(){
WebObjectKeeper.setWebObjcet(new WebObject());
foo(WebObjectKeeper.getWebObject());
foo2();
}
public void foo2(){
WebObjectKeeper.getWebObject().executeThisMethod();
System.out.println("Object = " + WebObjectKeeper.getWebObject());
}

Java method which takes unknown parameter

Is there a way in java to write a method which will take an unknown object as a parameter? The objects will always have a common method which the method will then need to call. Here is an example:
public void aMethod (MultipleObjects object){
object.commonMethod();
// Do some stuff here
}
I'm not sure what this is called (if it exists) so its difficult to search on Google.
You need an interface:
interface MyInterface {
void commonMethod();
}
class MyClass implements MyInterface {
// implement `commonMethod()`
}
Now your method would be:
public void aMethod(MyInterface object) {
...
object.commonMethod();
...
}
You can now pass an instance of MyClass (or any other class that implements MyInterface) to aMethod().
You can make all those classes (which share the common method) to implement an interface, so you define the method like:
public void aMethod(SomeInterface obj) {
obj.commonMethod();
// ...
}
The interface would be:
public interface SomeInterface {
public void commonMethod();
}
The usual way to do this is to define an interface that has just that method in it, then make sure all the classes that you might pass to aMethod implement that interface. E.g.:
interface CommonMethodHaver {
void commonMethod();
}
class Class1 implements CommonMethodHaver {
yadda yadda yadda;
void commonMethod() {
do class1-specific stuff here;
}
}
...
public void aMethod(CommonMethodHaver cmh) {
cmh.commonMethod();
// Do some stuff here
}
If you truly don't know what objects will be passed in and those object are not related through any kind of common base class or interface, then you will need to pass the object in as an Object reference and use reflection to find out if the object implements the method you want to call. If it does, then you again use reflection to call it.
I understand a lot of people are interpreting your question to mean you want to know about interfaces but I am interpreting this "write a method which will take an unknown object as a parameter?" to mean how do I write a method to handle unknown objects. As the other answers already tell you unless they share a common interface you can't have them all call the same method. But in case you are asking for this(which is what I think your question is asking for) this is how you would custom handle different unknown parameters...
public void aMethod(Object... object) {
if(object==null)
{
//whatever you want to do if no parameters are entered.
return;
}
for (Object o : object) {
if (o == null) {
continue; //what to do if null entered
}
if (o instanceof Integer) {
//whatever you want to do if it is an Integer
}
else if(o instanceof Double)
{
//whatever you want to do if it is a Double
}
else if(o instanceof Character)
{
//whatever you want to do if it is a Character
}
//and so on
}
}

Overriding a method in an instantiated Java object

I would like to override a method in an object that's handed to me by a factory that I have little control over.
My specific problem is that I want to override the getInputStream and getOutputStream of a Socket object to perform wire logging.
The generic problem is as follows:
public class Foo {
public Bar doBar() {
// Some activity
}
}
Where I'd like to take an instantiated Foo and replace the doBar with my own that would work as follows:
Bar doBar() {
// My own activity
return original.doBar();
}
For the Socket I'm going to return an InputStream and OutputStream that are wrapped by logging to intercept the data.
Since Java uses class-based OO, this is impossible. What you can do is use the decorator pattern, i.e. write a wrapper for the object that returns the wrapped streams.
I think there is a way to achieve the effect you want. I saw it orriginally used in swing with buttons to allow the programmer to make the button do something when it is clicked.
Say you have your Foo class:
public class Foo {
public Bar doBar() {
// Some activity
}
}
Then you have a runner class or something similar. You can override the doBar() method at the point of instantiation and it will only affect that specific object.
that class may look like this:
public class FooInstance{
Foo F1 = new Foo(){
public Bar doBar(){
//new activity
}
}
Foo F2 = new Foo();
F1.doBar(); //does the new activity
F2.doBar(); //does the original activity found in the class
}
I'm not entirely sure that will do the trick for you but maybe it'll set you in the right direction. If nothing else it is possible to override a method outside of the class, maybe that will help you.
You can't replace methods in existing objects - you can't change an existing object's type, for one thing.
You could create a new instance of another class which delegated to the existing instance, but that has limitations too.
In your real world case is there no way you can simply make a separate call to wrap the streams returned by the socket? Can you give more details.
You can't really change an object on the fly in java.
You could have something which do what you want by wrapping your Foo into another similar objet which will delegate every call to Foo and at the same log everything you want. (see Proxy)
But if you want to do logging, maybe aspect is a better choice. (see AspectJ)
Using a decorator is the right way to go:
Some very similar code to the requirement you have with sockets is here:
http://www.javaspecialists.eu/archive/Issue058.html
Another proxying-related solution: you could use Aspects to override a method on a given object without subclassing it yourself. This is especially appropriate and common for logging. This example uses spring-aop.
class Example {
final Foo foo;
Example(Foo original) {
AspectJProxyFactory factory = new AspectJProxyFactory();
factory.setTarget(original);
factory.addAspect(FooAspect.class);
foo = (Foo) factory.getProxy();
}
#Aspect
static class FooAspect {
#Before("execution(Foo.doBar())")
Object beforeDoBar() {
// My own activity
}
}
If Socket was an interface then you could create a dynamic proxy. Below is an example. I put this here in case other people need to do this and the target instance is an instance of an interface.
The main reason this will not work for Socket is because java.lang.reflect.Proxy.newProxyInstance requires an array of interfaces for its second argument, so classes won't work here. As such for this example I had to create an interface called ParentInterface, which just has the three print methods.
public class Parent implements ParentInterface {
#Override
public void print1() {
System.out.println("parent 1");
}
#Override
public void print2() {
System.out.println("parent 2");
}
#Override
public void print3() {
System.out.println("parent 3");
}
public static void main(String[] args) {
Parent originalInstance = new Parent();
ParentInterface proxied = (ParentInterface) java.lang.reflect.Proxy.newProxyInstance(
Parent.class.getClassLoader(),
new Class[]{ParentInterface.class},
new ParentProxy(originalInstance));
proxied.print1();
proxied.print2();
proxied.print3();
}
static class ParentProxy implements InvocationHandler {
final Object realObject;
public ParentProxy(Object real) {
realObject = real;
}
#Override
public Object invoke(Object target, Method m, Object[] args) throws Throwable {
try {
if (m.getName().equals("print2")) {
print2();
return null;
} else {
return m.invoke(realObject, args);
}
} catch (java.lang.reflect.InvocationTargetException e) {
throw e.getTargetException();
}
}
public void print2() {
System.out.println("wrapper 2");
}
}
}
I'm not sure if this is possible. Have you considered creating your own class, having the object returned by the factory as a member, and then writing the doBar() method for that class.
two options:
easy : if Foo were you implemetn an interface you can use a Dynamic proxy to add new functionality.
more work: what you have is an "around" advice of AOP - you can use any of the existing AOP tools to make that possible. Spring Framework can do it for you, if you are using it already.

Categories