Mar*_*ett 1 java generics reflection collections jar
我正在尝试围绕其他所有都具有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 );
...
}};
Run Code Online (Sandbox Code Playgroud)
但是我想让用户在不使用args的情况下运行命令,并列出类及其操作。从以前的工作来看,大多数类确实都有描述。
我决定在一个界面中对此进行形式化:
public interface HasDescription {
String getDescription();
}
Run Code Online (Sandbox Code Playgroud)
然后:
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 ...
}
Run Code Online (Sandbox Code Playgroud)
但是我不确定如何声明它,我有很多变体。这是一个无效的示例:
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 );
}};
Run Code Online (Sandbox Code Playgroud)
变体/教训:
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。您不会使用这样的类型参数。类型参数可以在类级别或方法级别声明。使用这样的字段声明,您必须使用通配符:
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 );
}};
Run Code Online (Sandbox Code Playgroud)
我都试过
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());
Run Code Online (Sandbox Code Playgroud)
然后您可以执行以下操作:
map.get("command1").getDescription();
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4945 次 |
最近记录: |