Pointless variable declaration in source code


    public static void hideMenuBar() {
        if (platform == 2) {
            try {
                String td = "processing.core.ThinkDifferent";
                Class<?> thinkDifferent = PApplet.class.getClassLoader().loadClass("processing.core.ThinkDifferent");
                thinkDifferent.getMethod("hideMenuBar").invoke((Object)null);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

What is the point of the variable td?

1 Like

Technically, thereā€™s no need to declare any variables here.

Just PApplet.class.getClassLoader().loadClass("processing.core.ThinkDifferent").getMethod("hideMenuBar").invoke((Object)null);

Why (Object) null?

Seems like bad/band-aid programming.

B/c ThinkDifferent is a class, ThinkDifferent.hideMenuBar() would only be allowed if if it happens to be a static method; otherwise weā€™d have to instantiate ThinkDifferent 1st, then invoke hideMenuBar() method over its instance object.

Either the method hideMenuBar() has some access restrictions, such as private or; it might not exist for other platforms besides MacOS!

For either case, weā€™re required to use reflection techniques in order to access members which have limited access permissions or itā€™s not 100% guaranteed to exist!

Keyword null represents the absence of an Object.

But still, using (cast) operator to identify it as an Object seems like a silly overzealous non-AI IDE advise which most devs trust too much!

Ok.

But what does the String td do?

As @GoToLoop pointed out null is a value not an object. An object reference having the value null means that it is not referencing any object at that moment.

So the function call .invoke(null) passes a null value and the invoke method must test for null to prevent a NPE (null pointer exception) being thrown.

The alternative .invoke((Object)null) passes a Null Object, so I suspect the developer is using the Null Object Pattern to avoid the null test and provide some default behaviour in the absence of an object.

The null versus (Object)null point just interested so I did a little research and discovered the Null Object Pattern, I have never used this pattern and do not know how to implement it so donā€™t ask me for further detail. :smiling_face_with_halo:

Nothing since td is not used in scope

Why is td dfined when it is never used?

Why is Class<?> thinkDifferent defined when a one-liner would work?

Why are td and thinkDifferent not final?

True but

chains many method invocations so if one throws an exception or fails to perform as expected then it can be quite difficult to find the problem. Separating them until the final code is proven is generally a good idea. You can always chain them together later but why bother hell would freeze over before you saw any efficiency benefit in this particular instance.

processing.core.ThinkDifferent.hideMenuBar is a public static native void.

because they only exist within the try block code so making them final is rather superfluous.

Probably a left over during the development and testing phase.

1 Like

Because processing.core.ThinkDifferent.hideMenuBar is indeed static and public (for whatever reason), it should be possible to just call processing.core.ThinkDifferent.hideMenuBar((Object) null).

No need for weird wrapper classes!

I also dunno why reflection was used to invoke the static & public method hideMenuBar().

But as I have mentioned before, maybe class ThinkDifferent only exists in MacOS.

And if we try to direct access ThinkDifferent on either Windows or Linux it could crash!

This method has the native modifier which is a non-access modifier used to access methods implemented in a language other than Java like C/C++.

So it not simply about invoking this method because if you look at the method definition in github you will see that the method has no body so has no implementation rather like an interface or abstract method.

I suspect that the class loader is not just loading the class but linking it to the mac OS so it can invoke the hideMenuBar there.

1 Like

It only invokes ThinkDifferent when os == 2

(Iā€™m assuming that signifies macOS)

Yes Processing has to know whether it is OSX, Windows or Linux so it can interact with it.

2 Likes

ā€œAnd if we try to direct access ThinkDifferent on either Windows or Linux it could crash!ā€

But it only gets called on macOS.

So why is this not the code?

ThinkDifferent.hideMenuBar();

hideMenuBar is static for sure.

Could work.

Given ThinkDifferent.hideMenuBar() is declared as native, what if its actual implementation is missing on both Windows & Linux?

However, maybe itā€™s possible to use a try/catch block to directly invoke those native methods w/o resorting to reflection techniques.

Seems the only thing to do is to try it :partying_face:

The sketch below has four methods that use the original Processing code and the alternative of a simple call to the methods in ThinkDifferent class. (Obviously this will only work on osx)

Keys ā€˜hā€™ & ā€˜sā€™ will hide / show using the original methods
Keys ā€˜qā€™ & ā€˜wā€™ will hide / show using direct calls to the ThinkDifferent class methods

If you try it they both work with notable feature, once the showMenuBar() method is invoked / called it is no longer possible to hide the menu bar a second time.

import processing.core.ThinkDifferent;

void setup() {
  size(400, 300);
}

void draw() {
  background(255, 200, 200);
}

void keyTyped() {
  if (key == 'h') hideBar();
  if (key == 's') showBar();
  if (key == 'q') hideBarAlt();
  if (key == 'w') showBarAlt();
}

void hideBarAlt() {
  if (platform == 2) {
    try {
      ThinkDifferent.hideMenuBar();
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

void showBarAlt() {
  if (platform == 2) {
    try {
      ThinkDifferent.showMenuBar();
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

void hideBar() {
  if (platform == 2) {
    try {
      String td = "processing.core.ThinkDifferent";
      Class<?> thinkDifferent = PApplet.class.getClassLoader().loadClass(td);
      thinkDifferent.getMethod("hideMenuBar").invoke((Object)null);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

void showBar() {
  if (platform == 2) {
    try {
      String td = "processing.core.ThinkDifferent";
      Class<?> thinkDifferent = PApplet.class.getClassLoader().loadClass(td);
      thinkDifferent.getMethod("showMenuBar").invoke((Object)null);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}