【问题标题】:Very simple Java Dynamic Casting非常简单的 Java 动态转换
【发布时间】:2012-01-18 18:41:57
【问题描述】:

简单的问题,但我花了一个多小时来解决这个问题。我的代码如下。我需要使 SomeClass sc 动态化。因此,您将类名作为字符串传递给函数,并使用该类代替静态 someClass。怎么办?

SomeClass sc;
if (someOtherClassObject instanceof SomeClass){
    sc=(SomeClass) someOtherClassObject;

我想要的是

public void castDynamic (String strClassName){
  //cast the classname referred by strClassName to SomeClass 
  //if it is the  instance of SomeClass
}

编辑: 以上是简化。实际代码是这样的

public void X(String className, RequestInterface request)
{
    //My current code is this, I need to change so that "XRequest"
    //can be any   class referred by "className", 
    //and "request.getRequest" the object belonging to "className" class
    //I don't want static XRequest xvr, it should be fetched dynamically

    XRequest xvr;
    if (request.getRequest() instanceof XRequest){
        xvr=(XRequest) request.getRequest();
        client.setRequest(xvr); 
    }
}

另一个简单的改写:我使用 request.getRequest() 得到一个对象。我不知道那个物体是什么。所以我需要将它转换为提供的类字符串名称。怎么做?就这样。 – SQC 13 分钟前

【问题讨论】:

  • 也许你应该在你的问题中描述你想要的结果。基于字符串创建类的实例与动态转换无关。你想创建一个以字符串类名开头的已知类的实例,还是想创建一个以字符串类名开头的任何类的实例?
  • 请查看更新后的问题(即使它有点令人困惑)。我正在创建的是一个接收类名的 api 调用,以及一个具有相同类名的对象。我需要将对象转换为方法中的类名(但请记住,我只有类名的字符串,而不是真正的类)。就这样。很简单。
  • 正确的方法是将该方法放入RequestInterface,然后您可以轻松调用它。除此之外,您需要使用 reflection 来检索要调用的方法。

标签: java dynamic casting


【解决方案1】:

你想实例化一个类的名字吗?

首先,你需要创建一个Class<?> 对象:

Class<?> cls = Class.forName(strClassName);

然后实例化 this(注意,这可能会引发各种异常 - 访问冲突、ClassNotFound、没有 public 没有参数的构造函数等)

Object instance = cls.newInstance();

然后你就可以投射了:

return (SomeClass) instance;

请确保您了解以下各项之间的区别:

  1. 一个类名称(大约是一个文件名)
  2. 一个类object(本质上是一个type信息)
  3. 一个类instance(这种类型的实际对象)

如果需要,您还可以将cls 对象转换为Class&lt;? extends SomeClass&gt; 类型。不过,它并没有给你太多。您可以将其内联到:

return (SomeClass)(Class.forName(strClassName).newInstance());

哦,但是您可以在实例化之前对cls 对象进行类型检查。因此,您只需实例化它,前提是它满足您的 API(实现您想要获得的接口)。

编辑:向反射添加更多示例代码。

例如:

if (cls.isInstance(request)) {
  // ...
}

对于调用方法,您要么需要知道可以转换为的接口,要么使用 reflectioncls 对象的 getMethod 方法):

Method getRequest = cls.getMethod("getRequest");
getRequest.invoke(request);

【讨论】:

  • 工作方式相同:cls.isInstance(request)
【解决方案2】:

您描述的问题没有明确定义。 强制转换是一个接受一个对象和一个类的操作,然后检查该对象是否是给定类的实例。

但是你说你需要cast(s) the classname referred by strClassName to SomeClass if it is the instance of SomeClass 的东西。换句话说,您正在寻找适用于两个类(而不是一个类和一个对象)的东西。

所以,我们需要重申这个问题。以下是三个可能的问题(+ 解决方案)我希望其中一个是您所需要的

// Problem 1: check whether "object" can be casted to the class 
// whose name is "className"
public void castDynamic(Object object, String className) {
  Class cls = Class.forName(className);
  cls.cast(object);
}

// Problem 2: check whether the class whose name is "className" 
// is a subclass of SomeClass (A is a subclass of B if A (transitively) 
// extends or implements B).
public void castDynamic(String className) {
  Class cls = Class.forName(className);
  SomeClass.class.asSubclass(cls);
}


// Problem 3: check whether SomeClass is a sublcass the class 
// whose name is "className"
public void castDynamic(String className) {
  Class cls = Class.forName(className);
  cls.asSubclass(SomeClass.class);
}

详细信息:http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#asSubclass(java.lang.Class)

【讨论】:

  • 谢谢。请在其中查看我的原始问题和 cmets 关于我想要的内容
【解决方案3】:

你的意思是?

 Class clazz = Class.forName(strClassName);

【讨论】:

  • 这个错误是由该演员下面的两行引起的。您将如何编写“if (){}”部分?
  • 你的最终目标是什么?当您以这种方式转换对象时,因为您需要使用该类的实例来做某事。
猜你喜欢
  • 1970-01-01
  • 2011-01-25
  • 2016-03-26
  • 2014-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-27
相关资源
最近更新 更多