Good afternoon, I began to study java just recently, a question appeared. In php, we can call a method like this:

$name = 'productController'; $action = 'run'; $controller = new $name; $controller->$action(); 

Tried to do something like that, it does not work. Is it possible to have such a call in java or is everything strictly and such freedom should not be expected? :)

  • one
    Not clear :))) - Flippy
  • one
    @ SergeyGrushin is quite understandable. Dynamically created object and method call - Alexey Shimansky
  • one
    @DaVASrK while only Reflection comes to mind - Alexey Shimansky
  • @ Alexey Shimansky thanks for the referral, I read it and try to do it through reflection - DaVASrK
  • The title of the question would be corrected, so that it was clearer what it was about ... - m. vokhm

3 answers 3

You can try a method called Reflection

Reflection in Java is used to view information about classes, interfaces, methods, fields, constructors, annotations during the execution of java programs. At the same time, it is not necessary to know the names of the elements studied in advance.

All classes for working with reflection are located in the java.lang.reflect .

With the help of reflection you can

  • Get information about class modifiers, fields, methods, constants, constructors, and superclasses.
  • Call an object method by name.
  • Find out which methods belong to the interface / interfaces being implemented. Create an instance of the class, and the name of the class is unknown until the execution of the program.
  • Get and set the value of an object field by name.
  • Learn / define object class
  • other

Example:

  MyClass obj = new MyClass(); // <--- это класс, который будем просматривать Class c = obj.getClass(); // Получение объекта типа Class Method[] methods = c.getDeclaredMethods(); // возвращаем все методы класса не зависимо от типа доступа for (Method method : methods) { System.out.println("Имя: " + method.getName()); System.out.println("Возвращаемый тип: " + method.getReturnType().getName()); Class[] paramTypes = method.getParameterTypes(); // берем параметры метода System.out.print("Типы параметров: "); for (Class paramType : paramTypes) { System.out.print(" " + paramType.getName()); } System.out.println(); System.out.println("------------------------"); } // Пример получения конкретного метода по имени Method method1 = с.getMethod("simple"); // Вызвать метод с помощью invoke - передать туда только объект String simple = (String)method1.invoke(c); 

If we do not know the name of the class at the time of compilation, but we know it at runtime, we can use the forName() method to get the Class object.

 Class obj = Class.forName("com.test.classes.MyClass"); 

Also instead

 MyClass obj = new MyClass(); // <--- это класс, который будем просматривать Class c = obj.getClass(); // Получение объекта типа Class 

You can write:

 Class obj = MyClass.class; 

Those. you do not need to create an instance of the class (which can call the constructor and rotate unknown manipulations), and we already know at the time of compilation what type it will be.

  • In principle, nothing complicated, thanks, I will understand now in practice :) - DaVASrK
  • @DaVASrK having studied something, it always becomes easy)) Good luck - Alexey Shimansky

If I understand correctly, you want to dynamically call methods or create objects based on the name.

In java for this purpose there are several tools of reflection , method handlers .

Wrote a small example:

 import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.Method; public class Solution { public static void main(String[] args) throws Throwable { String methodName = "greeter"; reflectionInvoker(methodName, Solution.class); methodHandlerInvoker(methodName,Solution.class); } private static void reflectionInvoker(String methodName, Class<?> clazz) throws Exception { Method method = clazz.getMethod(methodName); method.invoke(null); } private static void methodHandlerInvoker(String methodName,Class<?>clazz) throws Throwable { MethodHandle methodHandle= MethodHandles.lookup().findStatic(clazz,methodName, MethodType.methodType(void.class)); methodHandle.invoke(); } public static void greeter() { System.out.println("hello world"); } } 
  • It was enough to edit your old answer and restore it, and not to produce another one. For the future ... - Alexey Shimansky
  • Exactly what is needed. I read the reflection in Java and try to do it, thanks! - DaVASrK
  • @DaVASrK use methodhandlers better, they are faster - Artem Konovalov
  • @Artem Konovalov well, thanks for the tip - DaVASrK

Everything is strict :) Java is a language with strict typification. Each variable belongs to a specific type. The type of a variable limits the set of values ​​that can be assigned to such a variable. If this is an object type (i.e., anyone other than primitive, of type int or double ), then the class to which this variable belongs has a clearly defined set of members (fields and methods), and only these members of the variable can be accessed. Inheritance provides some flexibility with the ability to use interfaces in conjunction with type casting and reflection (the ability to learn everything you need about the class of an object if we have an object of unknown type).