Java:您能将类强制转换为特定的接口吗?

Java:您能将类强制转换为特定的接口吗?,java,class,Java,Class,我有一个项目,我正在工作,在这个项目中,我想包括开发人员的能力,包括他们自己的插件,而不必改变整个代码 到目前为止,这是我为它开发的。 这是插件正在使用的接口 package com.pennion.pennpad; public interface action{ void doAction(); } 这是加载插件的主代码 Map menuMap=new HashMap(); Map actionCommands=new HashMap(); public void load

我有一个项目,我正在工作,在这个项目中,我想包括开发人员的能力,包括他们自己的插件,而不必改变整个代码

到目前为止,这是我为它开发的。 这是插件正在使用的接口


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中


有没有更简单的方法来处理加载的字符串请求哪个KeyEvent?

您不能将类直接强制转换到某个对象

您可以创建它的对象,然后将其强制转换到接口

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

按照惯例,类名以大写开头。

到目前为止,在您显示的代码中,您只有一个
类,而不是该类的实例

在某些时候,您需要从
构造一个实例;该实例就是您将对
操作
强制转换的实例

/* 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();
/*加载插件类*/
Class clz=Class.forName(“com.y.plugins.MyCustomAction”);
/*确保指定的类是正确的类型*/

类对于第一个问题,您必须创建一个已加载类的实例,然后对其进行强制转换

所以


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

很抱歉,代码中没有注释,我仍在编写中。。实践错误的编码习惯=对于第二个问题,您可以考虑在字符串和KEYEVER常量之间进行映射。如果将“Map actionCommands=new HashMap();”更改为“Map actionCommands=new HashMap();”,是否有帮助?(或者类似的,您没有指定如何使用地图)。注意,尝试使用泛型使您的代码在您使用的类型中更显式。奇怪的是,建议在我将映射粘贴到文件上时如何在文件中对其进行编码,而不是复制…接口名称应以大写字母开头,如Action。我知道,我需要更改接口名称,因为javax.swing.Action已经存在,因此编译器会抛出错误。您不能直接实例化为接口,例如
Action actionObj=clazz.createNewInstance()
类上没有
createNewInstance()
方法。。我只是凭记忆写作。编辑。除非有类的实例,否则不能直接强制转换。实际上,不需要为此获取构造函数,默认情况下(无参数),可以直接在类对象上调用newInstance。@Marcos Vasconcelos-为了与动态方法调用保持一致,我更喜欢使用较新的API(获取构造函数)。首先,您可以获得更好的错误报告;如果构造函数不存在,则会得到一个
NoSuchMethodException
,而不是
IllegalAccessException
(这也可能意味着构造函数存在但不可访问)。
cInstance = c.newInstance();
((action)cInstance).doAction();