DZone
Java Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Java Zone > On Using the Right Tool for the Job

On Using the Right Tool for the Job

Baruch Sadogursky user avatar by
Baruch Sadogursky
·
Jun. 01, 12 · Java Zone · Interview
Like (0)
Save
Tweet
3.69K Views

Join the DZone community and get the full member experience.

Join For Free
disclaimer: the code samples in the post below are for brain teasing only. do not, i repeat, do not ever do such things for any other purpose!

a friend of mine is a big fan of puzzlers. any puzzlers, including programming ones. here’s his latest and greatest:

write some code in the static initializer to make the assert pass:

public class test {
 static {
//write some code here
 }

public static void main(string[] args) {
 integer a = 20;
 integer b = 20;
 assert (a + b == 60);
 }
}

don’t forget to enable assertions if you want to solve this one (-ea as vm parameter).

if you solved it, or don’t feel like puzzlers, read on for the solution and the punchline.

first, the solution: you need to know refection and two facts about integers to solve this one:

  1. integers have cache for all values in range -128 to 127.
  2. integers use that cache during auto-boxing (as opposite to using integer’s constructor, for example).

well, you also need to know the exact implementation of the integer class to figure out where the cache is and what’s the name, but rt.jar sources are here for the rescue. guess what? the cache is a private variable inside a private inner class. joy-joy.

here’s the plan:

  1. get integer’s class object.
  2. get the list of its inner classes.
  3. find the right one (what a relief, it only has one. or not – it is subject to change in future versions since we are digging in highly encapsulated stuff . duh.)
  4. get the cache field from it.
  5. it’s private, set it to accessible in order to get the value of the field.
  6. change the value of “20″ to be “30″

here’s the code of the static initializer:

 static {
try {
 class<?>[] declaredclasses = integer.class.getdeclaredclasses();
 field cachefield = declaredclasses[0].getdeclaredfield("cache");
 cachefield.setaccessible(true);
 ((integer[]) cachefield.get(null))[20 + 128] = 30;
 } catch (exception e) { e.printstacktrace(); }
 }

personally, i hate it. it’s ugly, it messes with very low-level encapuslated stuff that one even doesn’t suppose to know, and it is fragile (e.g. it won’t work if integer is created with constructor).

and fairly, we just got lucky. if integers did not have the cache then we would not  have any way to change what “+” does!

so, why this simple trick is so difficult to impossible to implement? simple – java is not intended for those tricks. java is static, and it is good! it means that you can rely on it. 20+20 will (almost always) be 40. that is good.

if you want to do dynamic stuff, like changing the behavior of  a “+” operator, you’d better use the right tool for the job. e.g. – groovy.

here’s the groovy version of the puzzler:

//write some code here
integer a = 20
integer b = 20
assert 60 == a + b

looks almost the same (without the main() mess, some ridiculous semicolons and the need to include -ea in vm parameters), but the difference in the way to achieve the desired is huge. since groovy is dynamic it is intended to do stuff like changing the behavior of the plus sign. here’s the facts about groovy that you need to know to solve this one:

  1. groovy operates with wrappers, always.
  2. groovy implements operators though methods. “+” is implemented in plus() method.
  3. using groovy’s metaclasses you can easily replace method with any closure.

here’s the plan:

  1. get integer’s metaclass.
  2. replace plus() method with implementation that returns 60.

that’s all. really. here’s the code:

integer.metaclass.plus = {int i -> 60 }

nuff said. now you only have 2 options. stop doing those ugly tricks, or at least do it with the right tools for the job.

career

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Your Old Laptop Is Your New Database Server
  • Choosing Between GraphQL Vs REST
  • Synchronization Methods for Many-To-Many Associations
  • How to Determine if Microservices Architecture Is Right for Your Business

Comments

Java Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo