[英]Java: can you cast Class into a specific interface?
I've got a project I am working on and in this project I would like to include the ability for developers to include their own plugins without having to change the whole code.我有一个我正在处理的项目,在这个项目中,我希望让开发人员能够在无需更改整个代码的情况下包含他们自己的插件。
This is what I have developed for it so far.到目前为止,这是我为它开发的。 this is the interface that the plugins are using.这是插件使用的界面。
package com.pennion.pennpad;
public interface action{
void doAction();
}
This is the main code that loads the plugins among other things.这是加载插件的主要代码。
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;
}
}
I need a way to cast the loaded class as an action because as of now it is being considered a class by the compiler and can't be added to the actionCommands hashmap.我需要一种将加载的类转换为动作的方法,因为到目前为止它被编译器视为一个类,并且不能添加到 actionCommands 哈希图中。
and is there an easier way to process which KeyEvent is being asked for by the loaded String?是否有更简单的方法来处理加载的字符串所要求的 KeyEvent?
You can't cast a Class direct to something.您不能将 Class 直接投射到某物上。
You can create a object of it and then cast it to your interface.您可以创建它的对象,然后将其转换为您的界面。
Object obj = clazz.newInstance();
Action actionObj = (Action) obj;
Follow the conventions, class names starts with upper case.遵循约定,类名以大写开头。
So far, in the code you show, you only have a Class
, not an instance of that class.到目前为止,在您显示的代码中,您只有一个Class
,而不是该类的实例。
At some point, you'll need to construct an instance from the Class
;在某些时候,您需要从Class
构造一个实例; that instance is what you'll cast to an Action
.该实例是您将转换为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();
For your 1st question, you will have to make an instance of the loaded class and then cast it..对于您的第一个问题,您必须创建一个已加载类的实例,然后对其进行转换。
So,所以,
cInstance = c.newInstance();
((action)cInstance).doAction();
For your 2nd question, I can't think of a quicker way to decode Strings into static variables.对于您的第二个问题,我想不出更快的方法将字符串解码为静态变量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.