Java:你可以将Class转换为特定的接口吗?

时间:2011-01-27 18:50:31

标签: java class

我有一个我正在研究的项目,在这个项目中,我想让开发人员能够包含他们自己的插件,而无需更改整个代码。

这是我迄今为止开发的内容。 这是插件正在使用的接口。


package com.pennion.pennpad;

public interface action{
 void doAction();
}

这是加载插件的主要代码。



 Map menuMap=new HashMap();
 Map actionCommands=new HashMap();
 public void load3rdPartyMenu() throws Exception{
  String userHome=System.getProperty("user.home");
  String sep=File.getSeparator();
  String fileString=userHome+sep+"pennion"+sep+"pennpad"+sep+"plugins"+sep+"plugins.conf";
  File cfgFile=new File(fileString);
  BufferedReader in=new BufferedReader(new InputStreamReader(new FileStreamReader(cfgFile)));
  String ln="";
  boolean menuFound=false;
  while((ln=in.readLine())!=null){
   if(!menuFound){
    if(ln.equals("//!==Menu!==//")){
     menuFound=true;
    } else{
     menuFound=false;
    }
   } else{
    String pluginName="";
    String pluginDescription="";
    String KeyMask="";
    String[] split=ln.split("||");
    pluginName=split[0];
    KeyMask=split[1];
    pluginDescription=split[2];
    ClassLoader pluginLoader=ClassLoader.getClassLoader();
    Class c=pluginLoader.loadClass("com.pennion.3rdparty."+pluginName);
    Map keyMap=new HashMap();
    String[] kmSplit=KeyMask.split("+");
    if(kmSplit[0].equals("CTRL")){
     keyMap.put("ActionEvent",ActionEvent.CTRL_MASK);
    } else if(kmSplit[0].equals("SHIFT")){
     keyMap.put("ActionEvent",ActionEvent.SHIFT_MASK);
    } else if(kmSplit[0].equals("ALT")){
     keyMap.put("ActionEvent",ActionEvent.ALT_MASK);
    } else if(kmSplit[0].equals("ALT_CTRL")||kmSplit[0].equals("CTRL_ALT")){
     keyMap.put("ActionEvent",ActionEvent.CTRL_MASK+ActionEvent.ALT_MASK);
    } else if(kmSplit[0].equals("SHIFT_CTRL")||kmSplit[0].equals("CTRL_SHIFT")){
     keyMap.put("ActionEvent",ActionEvent.CTRL_MASK+ActionEvent.SHIFT_MASK);
    } else if(kmSplit[0].equals("ALT_SHIFT")||kmSplit[0].equals("SHIFT_ALT")){
     keyMap.put("ActionEvent",ActionEvent.SHIFT_MASK+ActionEvent.ALT_MASK);
    }
    keyMap.put("KeyBind",getKeyBinding(kmSplit[1]));
    this.addMenuItem("Plugin",pluginName,keyMap.get("KeyBind"),keyMap.get("ActionEvent"),keyMap.get("KeyBind"),pluginName,c);
   }
  }
 }
 public int getKeyBinding(String k){
  if(k.equals("A")){
   return KeyEvent.VK_A;
  } else if(k.equals("B")){
   return KeyEvent.VK_B;
  } else if(k.equals("C")){
   return KeyEvent.VK_C;
  } else if(k.equals("D")){
   return KeyEvent.VK_D;
  } else if(k.equals("E")){
   return KeyEvent.VK_E;
  } else if(k.equals("F")){
   return KeyEvent.VK_F;
  } else if(k.equals("G")){
   return KeyEvent.VK_G;
  } else if(k.equals("H")){
   return KeyEvent.VK_H;
  } else if(k.equals("I")){
   return KeyEvent.VK_I;
  } else if(k.equals("J")){
   return KeyEvent.VK_J;
  } else if(k.equals("K")){
   return KeyEvent.VK_K;
  } else if(k.equals("L")){
   return KeyEvent.VK_L;
  } else if(k.equals("M")){
   return KeyEvent.VK_M;
  } else if(k.equals("N")){
   return KeyEvent.VK_N;
  } else if(k.equals("O")){
   return KeyEvent.VK_O;
  } else if(k.equals("P")){
   return KeyEvent.VK_P;
  } else if(k.equals("Q")){
   return KeyEvent.VK_Q;
  } else if(k.equals("R")){
   return KeyEvent.VK_R;
  } else if(k.equals("S")){
   return KeyEvent.VK_S;
  } else if(k.equals("T")){
   return KeyEvent.VK_T;
  } else if(k.equals("U")){
   return KeyEvent.VK_U;
  } else if(k.equals("V")){
   return KeyEvent.VK_V;
  } else if(k.equals("W")){
   return KeyEvent.VK_W;
  } else if(k.equals("X")){
   return KeyEvent.VK_X;
  } else if(k.equals("Y")){
   return KeyEvent.VK_Y;
  } else if(k.equals("Z")){
   return KeyEvent.VK_Z;
  } else if(k.equals("1")){
   return KeyEvent.VK_1;
  } else if(k.equals("2")){
   return KeyEvent.VK_2;
  } else if(k.equals("3")){
   return KeyEvent.VK_3;
  } else if(k.equals("4")){
   return KeyEvent.VK_4;
  } else if(k.equals("5")){
   return KeyEvent.VK_5;
  } else if(k.equals("6")){
   return KeyEvent.VK_6;
  } else if(k.equals("7")){
   return KeyEvent.VK_7;
  } else if(k.equals("8")){
   return KeyEvent.VK_8;
  } else if(k.equals("9")){
   return KeyEvent.VK_9;
  } else if(k.equals("0")){
   return KeyEvent.VK_0;
  } else{
   return 0;
  }
 }

我需要一种将加载的类强制转换为动作的方法,因为到目前为止,它被编译器视为一个类,无法添加到actionCommands hashmap中。

是否有更简单的方法来处理加载的String要求哪个KeyEvent?

3 个答案:

答案 0 :(得分:7)

你不能直接将类强制转换为某种东西。

您可以创建它的对象,然后将其投射到您的界面。

Object obj = clazz.newInstance();
Action actionObj = (Action) obj;

遵循惯例,类名以大写字母开头。

答案 1 :(得分:4)

到目前为止,在您展示的代码中,您只有Class,而不是该类的实例。

在某些时候,您需要从Class构建一个实例;该实例是您将投射到Action的内容。

/* Load the plugin class. */
Class<?> clz = Class.forName("com.y.plugins.MyCustomAction");
/* Make sure the named class is the right type. */
Class<? extends Action> sub = clz.asSubclass(Action.class);
/* Get the default constructor. */
Constructor<? extends Action> ctor = sub.getConstructor();
/* Create an instance of "MyCustomAction". */
Action custom = ctor.newInstance();

答案 2 :(得分:0)

对于您的第一个问题,您必须创建已加载类的实例,然后将其转换为..

所以,

cInstance = c.newInstance();
((action)cInstance).doAction();

对于你的第二个问题,我想不出更快的方法将字符串解码为静态变量。