我正在尝试围绕其他所有具有main方法的类执行命令行包装器类。
我已经向类声明了一个字符串映射,但现在我想确保所有类都实现一个特定的接口。
这个想法是你给一个别名别名或“命令名称”作为第一个参数,然后我会调用该类的主要部分并将其余的argv数组传递给它。
最初我有这个:
static final Map<String, Class> CLASSES = new LinkedHashMap<String,Class>() {{
put( "command1", com.foobar.package_a.ClassOne.class );
put( "command2", com.foobar.package_a.ClassTwo.class );
put( "command3", com.foobar.package_b.ClassThree.class );
...
}};
但是我想让用户在没有args的情况下运行命令并列出类和它们的作用。从以前的工作中,大多数课程都有描述。
我决定在界面中将其正式化:
public interface HasDescription {
String getDescription();
}
然后:
public class ClassOne implements HasDescription {
// I'd prefer static, but that's a different concern
public String getDescription() {
return "check files for gophers";
}
... rest of class ...
}
但我不知道如何宣布它,我有很多变化。以下是不工作的一个示例:
static final Map<String, Class<T implements HasDescription>> CLASSES = new LinkedHashMap<String,Class<T implements HasDescription>>() {{
put( "command1", com.foobar.package_a.ClassOne.class );
put( "command2", com.foobar.package_a.ClassTwo.class );
put( "command3", com.foobar.package_b.ClassThree.class );
}};
变化/教训:
implements
和extends
new LinkedHashMap<>()
问题:
为什么我这样做?
java -jar projname.jar command_name arg1 arg2 arg3
java -jar projname.jar
运行,则会获得一个类列表及其执行的操作java -cp projname.jar com.foobar.package_a.ClassOne arg1 arg2 arg3
运行,但这对于输入的人来说有点难看,并且每个类名都需要.sh和.bat。答案 0 :(得分:4)
您不使用类似的类型参数。类型参数可以在类级别或方法级别中声明。使用这样的字段声明,您必须使用通配符:
static final Map<String, Class<? extends HasDescription>> CLASSES = new LinkedHashMap<String,Class<? extends HasDescription>>() {{
put( "command1", com.foobar.package_a.ClassOne.class );
put( "command2", com.foobar.package_a.ClassTwo.class );
put( "command3", com.foobar.package_b.ClassThree.class );
}};
我已经尝试了
implements
和extends
在泛型中,您只需使用extends
关键字来表示这两个概念。
理想情况下.getDescription()将是静态的。
不,你不能那样做。这不会给你目前想要的多态行为。
如果拉出一个合格的类变量,是否有一个快捷方式或特殊版本的反射,只是让我说
( (HasDescription)clazz ).getDescription()
之类的东西?
如果要调用这样的方法,那么为什么要存储Class
实例而不是实例本身?如果要存储Class
实例,则必须使用Class#newInstance()
方法对其进行实例化,并确保所有实现类都为此提供0-arg构造函数。
指定所有类必须实现特定接口是否在这种使用场景中为我买了什么?
如果您要存储Class
实例,那么您必须这样做。但是如果您自己存储实例,那么只需将引用保留为HasDescription
就可以了:
static final Map<String, HasDescription> map = new LinkedHashMap<>();
map.put("command1", new com.foobar.package_a.ClassOne());
map.put("command2", new com.foobar.package_a.ClassTwo());
然后你可以这样做:
map.get("command1").getDescription();
答案 1 :(得分:1)
您不会在字符串中将接口声明为类映射。您可以通过使用以下内容来查看特定类是否实现了接口:
Class<?> testClass = [ lookup your class, or test class before adding to your map];
boolean isProperInterface = HasDescription.class.isAssignableFrom(testClass);
(在不同情况下,您可以使用
检查对象是否是类或接口的实例 boolean isGood = object instanceof [class or interface name]