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();