Cute tricks with Java Static Fields

This is something interesting I came across the other day, when I wanted to dynamically evaluate a static field on a Java class, and I thought it was a clever trick that was worth sharing.

First of all, what is a 'static field'?  Well here is a really good description of a static variable, but the short version is that it something that is available without an instance of a class.  This is functionality that can't be done in ColdFusion, but it is available in Java, and some other languages.

So if we look at a java.lang.Math we can see it has two static fields, one for pi, 'PI' and one for the value of e, 'E'.

In Java, we would be able to access these simply by going:
INT circumference =  java.lang.Math.PI * diameter;

and if we wanted to do that in ColdFusion, we would have to do:


<cfscript>
    Math = createObject("java", "java.lang.Math");
    circumference = Math.PI * diameter;
</cfscript>


Now, what would we do, if we weren't sure if 'PI' existed on the Math class? In Java we'd have to do some reflection , but in ColdFusion, it is really, really easy:


<cfscript>
    hasPI = StructKeyExists(Math, "PI");
</cfscript>


Yes – you can use Struct functions on the Java class to resolve public variables! Interesting, no?

So now, if we wanted to evaluate 'PI', we now have three options:


<cfscript>
    piOne = Math.PI; //as before
    piTwo = Math["PI"]; //dynamically evaluate
    piThree = StructFind(Math, "PI");
</cfscript>


And all three will result in the same value.

This can be very handy when wanting to allow access to Java static fields on Class, but you don't want to be passing around a Java Object – now you can create a Facade to those Java objects, and ask for them dynamically.

I'm sure someone else can come up with a cleverer way to use this trick, but I found it useful.

Leave a Comment

Comments

  • PaulH | January 24, 2007

    yeah i suppose the API/javadocs aren’t any good these days 😉

    good tip for dynamic evaluation.

  • Mark | January 26, 2007

    You’d be right Paul :oD, the case this came from is where I’m doing a lot of stuff with some code that generates Java for me, and one of things that is generated is a slew of static fields, so it is very handy for me to be able to dynamically evaluate them.

  • Amir | January 31, 2007

    Why not just cfdump your object ?

  • Mark | February 1, 2007

    Amir,

    This is handy if you want to dynamically evaluate fields on a Java object. Which, is pretty handy if you don’t know them ahead of time.

  • LUis Majano | February 17, 2007

    This trick is also useful when auto populating cfc beans or java beans. You can instantiate the object, then check for the existence of the method:
    <cfif structKeyExists(myBean, "setName")>
    <cfset myBean.setName("name")>
    </cfif>

    Very useful.

  • Martin Orth | May 22, 2007

    > you can’t dynamically change the inheritance structure of the CFC at run time

    I can be done. Create three CFCs and try a getMetaData() inside the first CFC. Here is the code:

    First CFC (mycfc1.cfc)

    <cfcomponent extends="mycfc2" hint="I am the first class.">

    <cfset stmetadata=getmetaData()>
    <cfset stmetadata.extends.name="mycfc3">
    <!— change the path to the right location of your CFCs —!>
    <cfset stmetadata.extends.path="C:CFusionMX7wwwrootmycfc3.cfc ">

    </cfcomponent>

    Second CFC (mycfc2.cfc)

    <cfcomponent hint="I am the second class.">

    <cffunction name="getString" returntype="string" output="No">

    <cfreturn "mycfc2">
    </cffunction>

    </cfcomponent>

    Third CFC (mycfc3.cfc)

    <cfcomponent hint="I am the third class.">

    <cffunction name="getString" returntype="string" output="No">

    <cfreturn "mycfc3">
    </cffunction>

    </cfcomponent>

    and now use this code to get a proof of concept

    <cfset obj = CreateObject(‘component’,’mycfc1′)/>
    <cfoutput>#obj.getString()#</cfoutput>
    <cfdump var="#getMetadata(obj)#" />

    Thanks

    Martin

  • Bibek Satapathy | July 18, 2007

    its well site for knowing facts in java.

  • Mike Causer | January 13, 2009

    @Martin Orth – doesn’t appear to work in cf8.