Class.forName and class.getConstructor

74 views
Skip to first unread message

dario...@gmail.com

unread,
May 25, 2016, 7:00:40 AM5/25/16
to CodenameOne Discussions

Hi,

I espone two question:


- why Class.forName has been deprecated?

Class cls = Class.forName(classname);


- and why getConstructor has been removed?

AppController controller = (AppController) cls.getConstructor(RoutingContext.class, Logger.class).newInstance(context, logger);


How I can to instance a class dinamically?


thanks 

Dario

Jérémy MARQUER

unread,
May 25, 2016, 7:36:10 AM5/25/16
to CodenameOne Discussions, dario...@gmail.com
1) I believe Class.forName(String name) is deprecated because classes names are rename on differents way according to the platform.

2) It require Java reflection which is not supported by CN1.

3) I think you could use "Class.newInstance()" method (not sure about that)

dario...@gmail.com

unread,
May 25, 2016, 9:07:44 AM5/25/16
to CodenameOne Discussions, dario...@gmail.com
thank you very much jeremy

Shai Almog

unread,
May 26, 2016, 12:27:01 AM5/26/16
to CodenameOne Discussions, dario...@gmail.com
Correct.
The main problem is that even on devices like Android we obfuscate the binaries as Google explicitly recommends so the class names will be garbled.

Since iOS doesn't allow dynamic code download there will be no class that is "unknown" on build time and thus there is no reason for class forName or reflection as both pose a very large overhead in AOT compilation (Ahead of time as opposed to typical Java JIT compilation).

Notice that if you need generic code that uses the Class object you can use class literals in a very portable and efficient way e.g.:

MyCommonInterface i = (MyCommonInterface)MyClass.class.newInstance();

This will be reasonably efficient on the device as it will translate to an indirect function pointer call.

dario...@gmail.com

unread,
May 26, 2016, 3:32:39 AM5/26/16
to CodenameOne Discussions, dario...@gmail.com
Hi Shai,
thank you for reply.

My singular request because I am trying to create a layer MVC on CD1 framework, so in same case I need to instance the Controller dinamically.

regards
Dario

Shai Almog

unread,
May 27, 2016, 1:11:23 AM5/27/16
to CodenameOne Discussions, dario...@gmail.com
Hi,
can you be more clear about what specifically you are trying to accomplish?

Using class.forName() won't give you an advantage of abstraction as you can't link code dynamically anyway.

Dario Licci

unread,
May 27, 2016, 4:16:28 AM5/27/16
to Shai Almog, CodenameOne Discussions
Hi Shai,
I try to explain.
In attach you can see the structure that I am realizing, for example, the application starts with the method called "Login" of "app.controller.UserController", in this method I set the layout that should be used (app.view.layout .LoginLayout). 
The controller method I instantiate the corresponding view (app.view.user.Login) that will present to me the classic form of authentication.

When authentic me the controller redirects me to the "Profile" method which uses the "app.view.layout.Default” layout, this layout I have also created the "Sidebar" where I wanted to use dynamic call other controllers.

I hope I explained it clearly.
Schermata 2016-05-27 alle 09.38.47.png

Shai Almog

unread,
May 28, 2016, 12:24:26 AM5/28/16
to CodenameOne Discussions, shai....@gmail.com, dario...@gmail.com
Hi,
so the way we do an abstraction of implementation is thru class literals. E.g. see the native interface support: https://www.codenameone.com/manual/advanced-topics.html#_native_interfaces

This works by using code such as:

MyNative my = NativeLookup.create(MyNative.class);
if(my != null && my.isSupported()) {
   
Log.p(my.helloWorld("Hi"));
}

Notice that "MyNative" is an interface not the implementation class and the build server injects the glue code to
the native code. Once it has that glue code in place it just does a put(class,impl) into the native lookup map
which we can then query for the real implementation.


Dave Dyer

unread,
May 30, 2016, 1:20:34 PM5/30/16
to CodenameOne Discussions, shai....@gmail.com, dario...@gmail.com
It's easy to replace use of class.forName with a hash map containing the finite list of classes you need to instantiate,
but one word of caution, if your list is extensive, conceal the list from the low level utility that replaces it, otherwise
all the headers for all the classes in the list become part of every class.   In my rather extreme case, doing so
resulted in a 50% reduction in IOS build time.

    static public Hashtable<String, Class<?>> namedClasses = new Hashtable<String,Class<?>>();

    public static Class<?> classForName(String name,boolean testOnly)
    {    Class<?>cl = namedClasses.get(name);
...}
Reply all
Reply to author
Forward
0 new messages