借助对象(在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();
}