|
Java reflection WTF
-
11-25-2008 3:40 PM
|
|
-
AJAXdrivenBuzzwords


- Joined on 04-21-2007
- Posts 7
|
Found some code today: if(object.getClass().getName().toString().indexOf("Double") >= 0) { double d= (double)object; //do some stuff with d
} Count the WTFs, include if you wish TRWTF is Java.
|
|
-
-
-
Ilya Ehrenburg


- Joined on 10-22-2008
- Ashkenas
- Posts 86
|
bstorer:Well, the good thing is that, other than being incredibly pointless, it
can't really cause any harm. It's not like you can somehow slip a
DoubleBuffer in there.
Unless
Java now has auto-unboxing, it won't compile as casting from reference
types to basic types isn't possible. But if it does, it will throw
ClassCastExceptions when it meets objects of class
DoubleSidedFloppyDisk, so that's WTF #1. Further
- indexOf(), because that invites abovementioned
ClassCastExceptions, also equals("Double") would be faster, at least if
object is not a Double
- toString(), because getName() already returns a String
- the whole thing instead of "if (object instanceof Double)"
So, feeling very generous, I see three major WTFs without looking hard.
|
|
-
-
-
AJAXdrivenBuzzwords


- Joined on 04-21-2007
- Posts 7
|
Ilya Ehrenburg:Unless
Java now has auto-unboxing, it won't compile as casting from reference
types to basic types isn't possible. But if it does, it will throw
ClassCastExceptions when it meets objects of class
DoubleSidedFloppyDisk, so that's WTF #1. Further... Java was given the gift of auto-boxing and auto-unboxing with Java 5.0 (or Java 1.5) or whatever the hell Sun is calling it these days. But otherwise good job finding the big three. Another interesting WTF is that Double can appear anywhere in the string so a class of BigDouble would also evaluate to true.
|
|
-
-
bstorer


- Joined on 02-01-2007
- Alexandria, VA
- Posts 2,333
|
Ilya Ehrenburg:Unless
Java now has auto-unboxing,
It does. Ilya Ehrenburg:it won't compile as casting from reference
types to basic types isn't possible.
Correct. I assume if it's in a project, it does compile, which means that object is of a type which is a primative wrapper. Ilya Ehrenburg:But if it does, it will throw
ClassCastExceptions when it meets objects of class
DoubleSidedFloppyDisk, so that's WTF #1.
Not quite. Java wouldn't let it compile in the first place unless object were declared to be of type Boolean, Byte, Character, Short, Integer, Long, Float, or Double (did I cover all of them?). If object is declared as, say, Object, it would never compile. It doesn't matter what type is referenced by object, javac will catch it unless it's declared as an unboxable type. Now it's possible that somewhere further up the line they are trying to cast something to one of the wrapper types, but that's not a problem with this particular section of code. Ilya Ehrenburg:Further
- indexOf(), because that invites abovementioned
ClassCastExceptions, also equals("Double") would be faster, at least if
object is not a Double
- toString(), because getName() already returns a String
- the whole thing instead of "if (object instanceof Double)"
All of which make it very pointless to do it the way it's been done, but they don't present any harm. Ilya Ehrenburg:So, feeling very generous, I see three major WTFs without looking hard.
Oh, no doubt it's a WTF.
|
|
-
-
bstorer


- Joined on 02-01-2007
- Alexandria, VA
- Posts 2,333
|
AJAXdrivenBuzzwords: But otherwise good job finding the big three. Another interesting WTF is that Double can appear anywhere in the string so a class of BigDouble would also evaluate to true.
And, again, the code would never compile in that case. I suppose you could do magic with the class loader for Double and fuck it up, but that's not special to this code.
|
|
-
-
amischiefr


- Joined on 06-11-2008
- North Florida
- Posts 217
|
bstorer:Not quite. Java wouldn't let it compile in the first place unless object were declared to be of type Boolean, Byte, Character, Short, Integer, Long, Float, or Double (did I cover all of them?). If object is declared as, say, Object, it would never compile. It doesn't matter what type is referenced by object, javac will catch it unless it's declared as an unboxable type. Now it's possible that somewhere further up the line they are trying to cast something to one of the wrapper types, but that's not a problem with this particular section of code. I just answered my own post with yours: it WILL compile IFF they are using reflection to send an object to the method. Say the method/class is in some JAR or compiled file somewhere and it takes an Object, the compiler will only check that you are sending an Object, since autoboxing will occur you will be sending an Object always, hence comiling.
|
|
-
-
bstorer


- Joined on 02-01-2007
- Alexandria, VA
- Posts 2,333
|
amischiefr: bstorer:Not quite. Java wouldn't let it compile in the first place unless object were declared to be of type Boolean, Byte, Character, Short, Integer, Long, Float, or Double (did I cover all of them?). If object is declared as, say, Object, it would never compile. It doesn't matter what type is referenced by object, javac will catch it unless it's declared as an unboxable type. Now it's possible that somewhere further up the line they are trying to cast something to one of the wrapper types, but that's not a problem with this particular section of code. I just answered my own post with yours: it WILL compile IFF they are using reflection to send an object to the method. Say the method/class is in some JAR or compiled file somewhere and it takes an Object, the compiler will only check that you are sending an Object, since autoboxing will occur you will be sending an Object always, hence comiling.
But in that case the JAR or class shouldn't have compiled in the first place. Javac doesn't care where you get object from, if it's not declared as a primitive wrapper, it's going to complain about inconvertable types. You can't do (double)(some Object reference). You have to do (double)(Double)(some Object reference), which isn't the case here.
|
|
-
-
amischiefr


- Joined on 06-11-2008
- North Florida
- Posts 217
|
bstorer: But in that case the JAR or class shouldn't have compiled in the first place. Javac doesn't care where you get object from, if it's not declared as a primitive wrapper, it's going to complain about inconvertable types. You can't do (double)(some Object reference). You have to do (double)(Double)(some Object reference), which isn't the case here.
If the class in question is a seperate class, and compiled seperately, from the one calling the method (through reflection) then it doesn't know whether or not the object was declared as a primitive wrapper or not. Try it, it should compile expecting objects that are sent to the method to be coming as primitive wrappers.
|
|
-
-
bstorer


- Joined on 02-01-2007
- Alexandria, VA
- Posts 2,333
|
amischiefr:If the class in question is a seperate class, and compiled seperately, from the one calling the method (through reflection) then it doesn't know whether or not the object was declared as a primitive wrapper or not. Try it, it should compile expecting objects that are sent to the method to be coming as primitive wrappers. Maybe I'm not understanding you. If you define some class Foo, which has a method bar, which looks like this:
public void bar (Object object) {
//blah, blah, blah
if(object.getClass().getName().toString().indexOf("Double") >= 0) {
double d= (double)object;
//do some stuff with d
}
}
It will not compile. Give it a shot. On the other hand, if you have a method like this:
public void bar (Object object) {
//blah, blah, blah
if(object.getClass().getName().toString().indexOf("Double") >= 0) {
double d= (double)object;
//do some stuff with d
}
}
And try to access it using Method.invoke, passing, for example, the String "banana" as the parameter, you'll get an IllegalArgumentException. Either way, this isn't anything to do with the code from the OP. If it compiles, then object is declared locally as a reference to a primitive wrapper, and is thus fine. Casting problems elsewhere are a separate issue, and are a WTF with or without this code.
|
|
-
-
APH


- Joined on 06-08-2007
- Posts 9
|
For those unfamiliar with Java, this should probably be implemented as: if(object instanceof java.lang.Double) { double d= ((java.lang.Double)object).doubleValue(); //not necessary with auto-boxing in Java 1.5 or greater
//do some stuff with d
}
|
|
-
-
bstorer


- Joined on 02-01-2007
- Alexandria, VA
- Posts 2,333
|
bstorer:On the other hand, if you have a method like this:
public void bar (Object object) { //blah, blah, blah if(object.getClass().getName().toString().indexOf("Double") >= 0) { double d= (double)object; //do some stuff with d } }
And try to access it using Method.invoke, passing, for example, the String "banana" as the parameter, you'll get an IllegalArgumentException. Either way, this isn't anything to do with the code from the OP. If it compiles, then object is declared locally as a reference to a primitive wrapper, and is thus fine. Casting problems elsewhere are a separate issue, and are a WTF with or without this code.
Shit. That's what I get for copy-pasting. It helps if I change the code, doesn't it? Let's try this again: On the other hand, if you have a method like this:
public void bar (Double object) { //blah, blah, blah if(object.getClass().getName().toString().indexOf("Double") >= 0) { double d= (double)object; //do some stuff with d } }
And try to access it using Method.invoke, passing, for example, the
String "banana" as the parameter, you'll get an
IllegalArgumentException. Either way, this isn't anything to do with
the code from the OP. If it compiles, then object is declared locally
as a reference to a primitive wrapper, and is thus fine. Casting
problems elsewhere are a separate issue, and are a WTF with or without
this code.
|
|
-
-
Zecc


- Joined on 06-12-2007
- Posts 377
|
APH: For those unfamiliar with Java, this should probably be implemented as: if(object instanceof java.lang.Double) { double d= ((java.lang.Double)object).doubleValue(); //not necessary with auto-boxing in Java 1.5 or greater
//do some stuff with d
}
Comes with free NullPointerException prevention!
If mixed metaphors were illegal, I'd be having an indigestion.
|
|
-
-
SlyEcho


- Joined on 07-01-2008
- Posts 12
|
APH: For those unfamiliar with Java, this should probably be implemented as: if(object instanceof java.lang.Double) { double d= ((java.lang.Double)object).doubleValue(); //not necessary with auto-boxing in Java 1.5 or greater
//do some stuff with d
}
I'd use java.lang.Number instead of java.lang.Double.
|
|
-
-
HypocriteWorld


- Joined on 04-04-2008
- Posts 64
|
TRWTF is Java and its type system. Anyways, we desperately need someone to write Strings Considered Harmful.
((lambda (f) (f f)) (lambda (f) (f f)))
|
|
-
-
savar


- Joined on 08-02-2006
- Posts 310
|
Couldn't Sun have saved the world some agony by doing this:
class String { String toString() { throw new Exception('You are an idiot.'); }
}
|
|
-
-
APH


- Joined on 06-08-2007
- Posts 9
|
SlyEcho: APH: For those unfamiliar with Java, this should probably be implemented as: if(object instanceof java.lang.Double) { double d= ((java.lang.Double)object).doubleValue(); //not necessary with auto-boxing in Java 1.5 or greater
//do some stuff with d
}
I'd use java.lang.Number instead of java.lang.Double. And that's why you'd be wrong. Maybe, just maybe, you'd want to treat Integers, Doubles, and BigDecimals differently?
|
|
-
-
amischiefr


- Joined on 06-11-2008
- North Florida
- Posts 217
|
savar:Couldn't Sun have saved the world some agony by doing this:
class String { String toString() { throw new Exception('You are an idiot.'); }
}
Oh you're a clever little troll aren't you! Yes because everybody who uses Java for anything is an idiot right? One of the most used languages out there, if not the most widely used, is the worst out there for everything right? Maybe you should just learn how to program and stop bitching about Java. It works just fine for me.
|
|
-
-
Farmer Brown


- Joined on 11-25-2008
- Posts 196
|
amischiefr:One of the most used languages out there, if not the most widely used, is the worst out there for everything right?
Interesting. I cannot remember the last time I used a native Java program or even had the JVM installed...
amischiefr: It works just fine for me.
Who are you trying to convince? Us or yourself?
|
|
-
-
TwelveBaud


- Joined on 06-03-2008
- Salona, VA
- Posts 114
|
amischiefr:Oh you're a clever little troll aren't you! Yes because everybody who uses Java for anything is an idiot right?
*sigh* Quit being righteously indignant. Getting upset over trolling just makes trolls happy. Besides, I don't think he was trolling. savar:Couldn't Sun have saved the world some agony by doing this: class String { String toString() { throw new Exception('You are an idiot.'); }
}
Yes, TRWTF is that you can toString() a String, and that that makes no sense to do whatsoever. But you forget that firstly, String is a subclass of Object, and therefore has to implement toString(), even if it could only logically consist of the single line "return this;", and secondly, because of the way the class hierarchy works, it's possible to be handed an object that's a String without knowing in advance that it's a String, so being able to call toString() on it and still get sane results anyway is important. Programmers are stupid often, myself included, but there are legitimate use cases for a lot of this stuff.
|
|
-
-
amischiefr


- Joined on 06-11-2008
- North Florida
- Posts 217
|
Farmer Brown:
Interesting. I cannot remember the last time I used a native Java program or even had the JVM installed...
Wow, you really are an idiot. Please do read up before you post complete ignorance alright? Here is one place you can start: http://www.langpop.com/ You must either be a highschool student or stupid. Java is used widely by businesses for internal applications(J2SE), phones (J2ME), web services and web sites (J2EE, JSP, AJAX ect.), both for internal and external applications. Just because you're one of those retards out there that thinks Java either isn't real or isn't used doesn't make it so.
|
|
-
-
morbiuswilters


- Joined on 01-15-2008
- East Coast Represent!
- Posts 3,150
|
amischiefr:You must either be a highschool student or stupid.
Why do you assume those are mutually exclusive? In the case of our new friend, I'm guessing it's an 11-year-old with nothing to do on Thanksgiving break who discovered the site through Digg, Reddit, Slashdot or one of the other Internet Malebolges. He will probably wear himself out soon or get grounded from the computer or accidentally kill himself in some moronic way.
< pstorer> Bans don't mean shit on the forum. It's like being on the Sex Offender List. You can still entice kids into your van with candy.
Want more? Go the IRC channel #TDWTFMafia on irc.slashnet.org.
|
|
-
-
Farmer Brown


- Joined on 11-25-2008
- Posts 196
|
amischiefr:Wow, you really are an idiot. Please do read up before you post complete ignorance alright?
Are you really disputing what software I use on my machine on a regular basis? I do think I know better than you do whether I have a JVM installed on any of my machines. I can very openly and honestly say I do not.
Your link does not refute that fact, so I am not sure what your point is.
amischiefr:You must either be a highschool student or stupid.
Why? Because I have not yet found a need for anything that uses the JVM? I don't follow you here.
amischiefr:Just because you're one of those retards out there that thinks Java either isn't real or isn't used doesn't make it so.
Maybe you responded to the wrong person. I said none of these things. I was just counter-relating your point to my experience. I don't use Java natively for anything on a daily basis. I don't even have a JVM installed. You arguing this makes me question your grasp of reality.
Again, your defensiveness seems to be some sort of emotional response, and I am not quite sure I understand it. Are you this torn about your decision in life to concentrate on Java?
|
|
-
|
|