Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
借助对象(在java运行时动态创建)打印方法 为了使我的问题变得简单,我举了一个简单的例子 我有一个类a,它有方法add()_Java_Object_Dynamic_Runtime - Fatal编程技术网

借助对象(在java运行时动态创建)打印方法 为了使我的问题变得简单,我举了一个简单的例子 我有一个类a,它有方法add()

借助对象(在java运行时动态创建)打印方法 为了使我的问题变得简单,我举了一个简单的例子 我有一个类a,它有方法add(),java,object,dynamic,runtime,Java,Object,Dynamic,Runtime,现在我想在运行时动态地创建它的对象 提供它的类名。我该怎么做,我已经写了 下面的代码,但它当然不工作 public class Practice{ public void add(){ System.out.println("add method"); } public static void main(String[] args) throws SQLException, ClassNotFoundException, InstantiationException, Ille

现在我想在运行时动态地创建它的对象 提供它的
类名。
我该怎么做,我已经写了 下面的代码,但它当然不工作

 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();
        }}
上面的代码不起作用,我不知道为什么,我无法找到我犯错误的地方,
第二件事
主方法中我定义了对象变量(在上面的代码中是xyz)**,我也想动态创建对象变量**

我上面的代码给了我以下的错误是

  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)
试试下面的

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

    }
}
接口Foo定义类A中的方法

 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();
  }
}

根据您的用例,您有多种选择:

  • 当您有多个类使用相同的方法时,只需创建一个包含该方法的
    接口
    ,并让所有其他类实现该接口

  • 当您还有一个动态方法时,您可以使用
    反射


对于第一种情况,您可以创建一个接口,在我的情况下是可添加的:

public interface Addable{
    void add();
}
然后让动态创建的所有类实现该接口:

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

public class B implements Addable {
    public void add(){
        // other logic
    }
}
在main方法中,您可以更改以下代码行:

Object xyz = 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);
}
publicstaticvoidmain(String[]args)抛出实例化异常、IllegalAccessException、ClassNotFoundException、NoSuchMethodException、InvocationTargetException{
字符串className=“A”;
String methodName=“添加”;
Class clazz=Class.forName(className);
方法Method=clazz.getDeclaredMethod(方法名);
对象实例=clazz.newInstance();
方法调用(实例);
}
要详细说明所做的工作:

  • 首先按名称加载类
  • 然后按名称获取方法
  • 创建该类的新实例
  • 调用该实例的方法

抛出的
ClassNotFoundException
表示类加载器找不到给定名称的类。但是,这并不意味着该类在项目中不存在。StringName与完整类名不匹配的可能性很高

类名不仅包括具体名称,还包括包

让我们假设我们有一节课

package foo.bar;

public class Test
{
  public void shout() 
  {
    System.out.println( "Hello World" );
  }
}
相应的类名也是字符串:
“foo.bar.Test”
,而不仅仅是
“Test”


此外,当使用反射实例化对象时,返回的类型为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();
}

我想动态创建对象变量


不幸的是,这是不可能的,因此您必须以另一种方式跟踪您的实例,例如将它们存储在数组、列表或任何其他类型的集合中。

请定义“不工作”。您是否收到任何编译错误、运行时异常或不正确的输出?使用选项来澄清您的问题。我在这里看不到
swing
元素。在旁注上,
public void add{
应该是
public void add(){
Stacktrace,您提供的代码与您发布的代码不匹配。无论如何,我怀疑您忘记了包含关于包的信息,所以没有使用
forName(“a”)
应该是
forName(“full.package.name.of.A”)
@shaunTait试图让你的例子尽可能简单是正确的选择,所以恭喜!但(1)注意不要包含与实际问题无关的问题(不要浪费那些愿意帮助你的人的时间,因为他们也会指出那些无关的问题)(2)确保可以用例子来重现你的问题为什么我们需要接口Foo,我们可以不用它吗?因为我们不知道类中提供的方法,使用接口解决了这个问题。哇,你让我开心,为什么你在编程方面如此完美,而我不是?
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();
}