Распечатать метод с помощью объекта (который динамически создается во время выполнения в Java) - PullRequest
0 голосов
/ 17 мая 2018
  1. Чтобы сделать мой вопрос простым, я привожу простой пример для примера: у меня есть class A, и у него есть метод add().
  2. , теперь я хочу create its object ввремя выполнения dynamically просто предоставив class name. как я могу это сделать, я написал следующий код, но конечно он не работает.

     public class Practice{
     public void add(){
     System.out.println("add method");
    
     }
        public static void main(String[] args) throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException {
    
            String className = "A";
            Object xyz = Class.forName(className).newInstance();
            xyz.add();
            }}
    

Приведенный выше код не работаетя не знаю почему, я не могу найти, где я делаю ошибку, и second thing в главном методе я определяю переменную объекта (которая в приведенном выше коде - xyz) **, я хочу c динамически создавать переменную объекта ** тоже.

мой код выше дает мне следующую ошибку

  Exception in thread "main" java.lang.ClassNotFoundException: Practice
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at practice.Practice.main(Practice.java:94)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)

Ответы [ 3 ]

0 голосов
/ 17 мая 2018

У вас есть несколько вариантов, в зависимости от вашего варианта использования:

  • Если у вас есть несколько классов с одним и тем же методом, просто создайте interface, содержащий этот метод, и пусть все другие классы реализуют этот интерфейс.

  • Если у вас также есть динамический метод, вы можете использовать reflection.


Для первого случая вы можете создать интерфейс, в моем случае Addable:

public interface Addable{
    void add();
}

И затем пусть все классы, которые могут быть созданы динамически, реализуют этот интерфейс:

public class A implements Addable {
    public void add(){
        // logic
    }
}

public class B implements Addable {
    public void add(){
        // other logic
    }
}

В вашем основном методе вы можете изменить строку кода с:

Object xyz = Class.forName(className).newInstance();

Кому:

Addable xyz = (Addable) Class.forName(className).newInstance();

Для второго случая с отражением:

public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException {
     String className = "A";
     String methodName = "add";
     Class<?> clazz = Class.forName(className);
     Method method = clazz.getDeclaredMethod(methodName);
     Object instance = clazz.newInstance();
     method.invoke(instance);
}

Чтобы уточнить, что было сделано:

  • сначала загрузите класс по имени
  • затем получите метод по имени
  • создать новый экземпляр этого класса
  • вызвать метод этого экземпляра
0 голосов
/ 17 мая 2018

Брошенный ClassNotFoundException указывает, что загрузчик классов не смог найти класс для данного имени. Однако это не означает, что класс не существует в проекте. Существует высокая вероятность того, что строка не соответствует полному имени класса.

Имя класса включает в себя не только конкретное имя, но и пакеты.

Предположим, у нас есть класс

package foo.bar;

public class Test
{
  public void shout() 
  {
    System.out.println( "Hello World" );
  }
}

также имя соответствующего класса в виде строки: "foo.bar.Test", а не просто "Test".


Также, когда вы создаете экземпляр объекта с помощью Reflection, возвращаемым типом является Object, и вы сохраняете его как единое целое, но при этом вы не можете получить доступ к методам класса:

String clazzname = "foo.bar.Test";
try
{
  Object obj = Class.forName( clazzname ).newInstance();
  //compiler error because java.lang.Object does not contain a method shout()
  obj.shout();
}

Но поскольку мы уверены, что возвращенный Объект является по крайней мере экземпляром самого себя, мы должны быть в состоянии безопасно привести его к нужному объекту:

String clazzname = "foo.bar.Test";
try
{
  foo.bar.Test obj = (foo.bar.Test)Class.forName( clazzname ).newInstance();
  // does work now since obj is now treated as a 'Test' object.
  obj.shout();
}

Я хочу создать переменную объекта динамически

К сожалению, это невозможно, поэтому вы должны отслеживать ваши экземпляры другим способом, например, сохраняя их в массиве или списке или любом другом виде.

0 голосов
/ 17 мая 2018

Попробуйте следующее.

public class A implements Foo
{
  public void add(){
    System.out.println("add method");

    }
}

Интерфейс Foo определяет методы в классе А.

 public interface Foo
    {
      void add();
    }

Как его вызывать.

public class test
{
  public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException
  {
    String className = "A";
    Foo xyz = (Foo) Class.forName(className).newInstance();
    xyz.add();
  }
}
...