Wrapper for multiple instanceof

G

getsanjay.sharma

Hello to all Java programmers out there.

Recently I have been trying to do a multiple instanceof and thought it
would be better to write a function than do those ugly || with
repeated instanceofs'.

public class MyInstance
{
public static boolean check(Object obj, String...classes) throws
Exception
{
boolean result = false;
for(String str : classes)
{
Class c = Class.forName(str);
result = result | (obj instanceof c);
if(result) break;
}
return(result);
}

public static void main(String args[]) throws Exception
{
String str = "hello";
String classes[] = {"String", "StringBuffer"};
System.out.println(MyInstance.check(str, classes));

}
}

I do very well realize that the instanceof operator requires a TYPE on
its RHS, but I can't seem to find out how to convert the class name
string to a type?

Is such kind of thing even possible here or doing multiple || with
instanceofs' is the only way to go?

Thanks and regards,
STS
 
J

Joshua Cranmer

Recently I have been trying to do a multiple instanceof and thought it
would be better to write a function than do those ugly || with
repeated instanceofs'.

Most instanceof's can be replaced with good OOP design.
public class MyInstance
{
public static boolean check(Object obj, String...classes) throws
Exception
{
boolean result = false;
for(String str : classes)
{
Class c = Class.forName(str);
result = result | (obj instanceof c);
if(result) break;
}
return(result);

Err.. ugly and uncompilable? The proper or for a boolean variable is ||
(short circuit boolean or) as opposed to | (bitwise or). This isn't C(++).

correct code:

for (String str : classes) {
Class<?> c = Class.forName(str);
if (c.isInstance(obj))
return true;
}
return false;


Even better would be to redeclare check as:
public static boolean check(Object obj, Class... classes)

circumventing the reflection needed.
}

public static void main(String args[]) throws Exception
{
String str = "hello";
String classes[] = {"String", "StringBuffer"};
System.out.println(MyInstance.check(str, classes));

Use varargs properly:
System.out.println(MyInstance.check(str,"String","StringBuffer"));

Or, using redefined check:
System.out.println(MyInstance.check(str,String.class,StringBuffer.class));
}
}

I do very well realize that the instanceof operator requires a TYPE on
its RHS, but I can't seem to find out how to convert the class name
string to a type?

By the nature of the underlying bytecode, the RHS of the instanceof
operator has to be known at compile time, rendering the ability to do
runtime loading impossible without using reflection. You started using
the Class class but seemed to have dropped off before getting to the
important part (it does have a method named instanceOf, after all).
Is such kind of thing even possible here or doing multiple || with
instanceofs' is the only way to go?

See above. I recommend, however, that the code be redesigned to avoid
using instanceof's if possible.
 
P

Patricia Shanahan

Joshua said:
Most instanceof's can be replaced with good OOP design.


Err.. ugly and uncompilable? The proper or for a boolean variable is ||
(short circuit boolean or) as opposed to | (bitwise or). This isn't C(++).

"|", in Java, is not just bitwise or. It is also a correct, but rarely
used, boolean operator, performing the same operation as "||" but always
evaluating the right hand side. See
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.22.2

In this case, it makes no difference which of "|" or "||" is used. The
left hand side is always false so the right hand side has to be
evaluated even with "||".

However, it is a good idea to make a habit of using "||" unless there
is a reason to force evaluation of the right hand side when the left
hand side is true.

Patricia
 
L

Lew

This idiom is a red flag that polymorphism should be used instead.

Define an interface, I'll call it "DoesSomething", with a method, say,
"doSomething()":

public interface DoesSomething
{
public void doSomething();
}

Then define implementing classes specific to your situation:

public class HelloWorld implements DoesSomething
{
private final String something;
public HelloWorld( String s )
{
something = s;
}
public void doSomething()
{
System.out.println( something );
}
}

In some client class you would have code like this:

DoesSomething doer = Factory.getDoesSomething();
// this factory method will deliver some implementation
// of DoesSomething depending on environment or data

doer.doSomething();

Notice the client code doesn't "know" that doer is "really" a HelloWorld, or
some other implementing class. It just lets the object "know" what to do for
itself. No run-time type checking needed on your part.

This idiom is at the heart of object-oriented programming.
 
B

Bent C Dalager

I do very well realize that the instanceof operator requires a TYPE on
its RHS, but I can't seem to find out how to convert the class name
string to a type?

Class stringClass = String.class;

Then you can use Class.isAssignableFrom() to do your checking.

Note that as others have pointed out, explicitly checking what class
an object is, is a danger sign (or a bad smell if you like). Chances
are there is a more appropriate way of accomplishing your goal using
polymorphism. Then again, sometimes there is not (this can typically
be the case when you need to work with third-party classes).

Cheers
Bent D
 
T

Twisted

public static boolean check(Object obj, String...classes) throws
Exception
{
boolean result = false;
for(String str : classes)
{
Class c = Class.forName(str);
result = result | (obj instanceof c);
if(result) break;
}
return(result);
}

Good Lord! When I saw the subject line I held my nose and clicked the
link to read the post, expecting something interesting but with a fair
bit of code smell.

This goes way beyond code smell -- I think maybe something crawled in
there and died!
 
G

getsanjay.sharma

Thanks a lot Joshua for putting things right, I knew there was some
bit missing, I guess it was the isInstance() method. And like Patricia
said, in this scenario the || or | didn't make a difference since I
was anyways breaking out of the loop if any of the class satisfied the
condition.

Thank you Patricia for clarifying in my absence, and oh, what we would
do without your JLS plugs. :)

(e-mail address removed) wrote:
[...]
Notice the client code doesn't "know" that doer is "really" a HelloWorld, or
some other implementing class. It just lets the object "know" what to do for
itself. No run-time type checking needed on your part.

This idiom is at the heart of object-oriented programming.

Thanks a lot Lew for letting me know of this. But this concept is
still a bit hazy to me. Can you provide a real world example on how
your paradigm can be put to use?

Thanks Roedy, like always, your link was really helpful. :)

And Bent, your method gave me an alternate solution to my problem.
Both isInstance() and isAssignableFrom() really seem to do the trick.
Thank you.

Good Lord! When I saw the subject line I held my nose and clicked the
link to read the post, expecting something interesting but with a fair
bit of code smell.

This goes way beyond code smell -- I think maybe something crawled in
there and died!

Its OK my friend, we all try to learn. Maybe by writing smelly code
but creative code today, I would live tomorrow to write better code...

Thanks and regards,
STS.
 
L

Lew

Thanks a lot Lew for letting me know of this. But this concept is
still a bit hazy to me. Can you provide a real world example on how
your paradigm can be put to use?

GIYF.

I already provided an example.
 
D

Daniel Pitts

Thanks a lot Joshua for putting things right, I knew there was some
bit missing, I guess it was the isInstance() method. And like Patricia
said, in this scenario the || or | didn't make a difference since I
was anyways breaking out of the loop if any of the class satisfied the
condition.

Thank you Patricia for clarifying in my absence, and oh, what we would
do without your JLS plugs. :)

(e-mail address removed) wrote:
[...]
Notice the client code doesn't "know" that doer is "really" a HelloWorld, or
some other implementing class. It just lets the object "know" what to do for
itself. No run-time type checking needed on your part.
This idiom is at the heart of object-oriented programming.

Thanks a lot Lew for letting me know of this. But this concept is
still a bit hazy to me. Can you provide a real world example on how
your paradigm can be put to use?

Thanks Roedy, like always, your link was really helpful. :)

And Bent, your method gave me an alternate solution to my problem.
Both isInstance() and isAssignableFrom() really seem to do the trick.
Thank you.

On Aug 21, 9:01 pm, (e-mail address removed) wrote:
Good Lord! When I saw the subject line I held my nose and clicked the
link to read the post, expecting something interesting but with a fair
bit of code smell.
This goes way beyond code smell -- I think maybe something crawled in
there and died!

Its OK my friend, we all try to learn. Maybe by writing smelly code
but creative code today, I would live tomorrow to write better code...

Thanks and regards,
STS.


Start with your the bad instanceof check:

class Foo {}
class Bar {}
class Baz {}


class NeedsToKnow {
public void needsToKnow(Object o) {
if ((o instanceof Foo) || o instanceof Bar) {
System.out.println("Fubar!");
} else {
System.out.println("Not Fubar!");
}
}
}

-----------

Refactoring to polymorphism gives you something like:


interface Knowable {
void needsToKnow();
}

abstract class Fubar implements Knowable{
public void needsToKnow() {
System.out.println("Fubar!");
}
}
/* Note, that these are free to further change the rules for
needsToKnow if they need to know.
class Foo extends Fubar {}
class Bar extends Fubar {}
class Baz implements Knowable {
public void needsToKnow() {
System.out.println("Not Fubar!");
}
}

class NeedsToKnow {
/* Note that Object o becomes Knowable o */
public void needsToKnow(Knowable o) {
/* Note the delegation. Tell, don't ask */
o.needsToKnow();
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top