【问题标题】:Search for a specific class and return it搜索特定类并返回
【发布时间】:2017-01-21 19:37:49
【问题描述】:

我有一个返回(在我的情况下)Block 的函数。 我有一个名为blockName 的字符串,其值将设置为“dirt”。 之后,我将创建一个名为 blockNameConverted 的新字符串。这将是BlockDirt,我还有一个类BlockDirt(它不在同一个包中):

public Block getBlockFromId(int id){

    String blockName = iBlockRegistry.getStrintFromId(id).getStringValue(); // Yeah i know.. it's Strint :D
    String blockNameConverted = "Block" + blockName.substring(0, 1).toUpperCase() + blockName.substring(1); //Capitalize the d of dirt

    debug.Log("Blockname: " + blockName);  //Outputs in Console "Blockname: dirt"
    debug.Log("Converted Blockname: " + blockNameConverted); //Outputs in Console "Converted Blockname: BlockDirt"

    Class<?> clas;
    try {
        clas = Class.forName(blockNameConverted);
    } catch (ClassNotFoundException e) {
        clas = BlockDirt.class.getClass(); //If class not found use this class as "default"
        e.printStackTrace();
    }
    Block blockClass = Block.class.cast(clas);

    return blockClass;
}

我认为clas = Class.forName(blockNameConverted); 应该搜索BlockDirt 类,但是当我调用此方法时出现此错误:

java.lang.ClassNotFoundException: BlockDirt
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at registry.MinecraftRegistry.getBlockFromId(MinecraftRegistry.java:39)
    at registry.BlockRegistry.register(BlockRegistry.java:11)
    at block.Block.registerBlock(Block.java:21)
    at engineTester.MainGameLoop.main(MainGameLoop.java:126)

还有这个:

Exception in thread "main" java.lang.ClassCastException: Cannot cast java.lang.Class to block.Block
    at java.lang.Class.cast(Unknown Source)
    at registry.MinecraftRegistry.getBlockFromId(MinecraftRegistry.java:44)
    at registry.BlockRegistry.register(BlockRegistry.java:11)
    at block.Block.registerBlock(Block.java:21)
    at engineTester.MainGameLoop.main(MainGameLoop.java:126)

我做错了什么?

我没有发布我的完整课程,因为我只想知道如何搜索课程并返回(或使用)它。

使用Block blockClass = Block.class.cast(clas);,我想得到与Block blockClass = new BlockDirt(); 相同的结果,但我不能直接在我的代码中输入这个,因为以后我还想创建其他块并且不想每次都获得BlockDirt 的ID .

我希望你能理解我,因为英语不是我的母语:D

【问题讨论】:

  • 您正在将 类本身 转换为块。它不是一个块。使用clas.newInstance() 创建该类的新实例。
  • 第一个异常只是意味着:类 BlockDirt 不在在运行你的代码的 JVM 的类路径中。
  • 两个不同的错误,两个不同的问题:1)ClassNotFoundException:你的类路径错误,和/或你没有指定正确的类名,2)ClassCastException:你必须强制转换块的类实例,而不是“类”对象”
  • 您可能应该使用BlockDirt 及其全名:com.test.BlockDirt for Class.forName
  • Class clazz = Class.forName("com.test.BlockDirt");

标签: java class casting


【解决方案1】:

java.lang.ClassNotFoundException: BlockDirt

您的第一个异常告诉您类BlockDirt 在类路径中不存在。您还需要正确的包名称。示例:

Class.forName("foo.bar.someprogram.BlockDirt");

在你的情况下,你可能需要这样的东西。

Class<? extends Block> myClass = Class.forName(myPackageName + blockNameConverted);

Cannot cast java.lang.Class to block.Block

您正在将类本身转换为Block。它不是Block。只有Block实例 可以转换为Block。使用myClass.newInstance() 创建该类的新实例。请记住,类的构造函数必须没有参数才能使此方法正常工作。如果您想使用多参数构造函数,您可以使用myClass.getConstructor(someParameters).newInstance(someArguments)

例子:

假设你的类有一个签名为BlockDirt(String name, int someNumber)的构造函数。

要使用此构造函数和反射创建一个新实例,请执行以下操作:

Block block = myClass.getConstructor(String.class, int.class).newInstance("Foo", 42);

请记住,您需要包名称才能使反射起作用。如果您知道它可能在哪些包中,您可以使用Jon Skeet's answer here

【讨论】:

  • 谢谢!我在设置blockNameConverted 时忘记了“--> PACKAGENAME. Block block = clas.getInstance();
猜你喜欢
  • 1970-01-01
  • 2017-05-07
  • 2018-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-20
  • 2016-01-14
相关资源
最近更新 更多