Java 使用字符串实例化类
假设我有圆类、矩形类和三角形类 基于数据文件的输入,我想创建适当的对象。例如,如果shapes.dat的第一行是C.5 0,我将创建半径为5的圆形对象。如果下一行是R.5 3 0,我将创建一个长度为5、宽度为3的矩形对象 我知道我可以使用基本的if-else逻辑,但我想知道是否有一种方法可以使用字符串作为实例化新对象的手段。有点像Python中的exec方法。下面是描述我想要什么的代码片段:Java 使用字符串实例化类,java,string,literals,Java,String,Literals,假设我有圆类、矩形类和三角形类 基于数据文件的输入,我想创建适当的对象。例如,如果shapes.dat的第一行是C.5 0,我将创建半径为5的圆形对象。如果下一行是R.5 3 0,我将创建一个长度为5、宽度为3的矩形对象 我知道我可以使用基本的if-else逻辑,但我想知道是否有一种方法可以使用字符串作为实例化新对象的手段。有点像Python中的exec方法。下面是描述我想要什么的代码片段: Scanner file = new Scanner (new File("shapes.dat
Scanner file = new Scanner (new File("shapes.dat"));
String s;
Map<Character,String> dict = new HashMap<Character,String>();
dict.put('C', "Circle");
dict.put('R', "Rectangle");
dict.put('T', "Triangle");
while (file.hasNextLine())
{
s = file.nextLine().trim();
String name = dict.get(s.toCharArray()[0]);
String data = s.split(".")[1];
String code = name + " x = new " + name + "(data);";
SYS.exec(code); //???
...
}
您可以利用反射动态创建实例
String className = "com.shape.Triangle";
Class classDefinition = Class.forName(className);
Object obj = classDefinition.newInstance();
或
只需使用if-else来创建特定类的实例 您可以利用反射动态创建实例
String className = "com.shape.Triangle";
Class classDefinition = Class.forName(className);
Object obj = classDefinition.newInstance();
或
只需使用if-else来创建特定类的实例 Python中的Exec执行代码。
您可以用Java做同样的事情,例如用javassist。
您可以读取数据文件,编译语句并将它们插入到自己的类中。
但这似乎有些过头了
您也可以使用java反射,但它会产生脆弱且不清晰的代码
相反,我认为应该使用抽象并按对象类型创建工厂类
它可能看起来像:
Scanner file = new Scanner (new File("shapes.dat"));
String s;
Map<Character, ShapeBuilder> dict = new HashMap<Character,String>();
dict.put('C', new CircleBuilder());
dict.put('R', new RectangleBuilder());
dict.put('T', new TriangleBuilder());
while (file.hasNextLine()){
s = file.nextLine().trim();
char shapeSymbol = ...; // computed from s
ShapeBuilder builder = dict.get(shapeSymbol);
Shape shape = builder.build(s);
}
Python中的Exec执行代码。
您可以用Java做同样的事情,例如用javassist。
您可以读取数据文件,编译语句并将它们插入到自己的类中。
但这似乎有些过头了
您也可以使用java反射,但它会产生脆弱且不清晰的代码
相反,我认为应该使用抽象并按对象类型创建工厂类
它可能看起来像:
Scanner file = new Scanner (new File("shapes.dat"));
String s;
Map<Character, ShapeBuilder> dict = new HashMap<Character,String>();
dict.put('C', new CircleBuilder());
dict.put('R', new RectangleBuilder());
dict.put('T', new TriangleBuilder());
while (file.hasNextLine()){
s = file.nextLine().trim();
char shapeSymbol = ...; // computed from s
ShapeBuilder builder = dict.get(shapeSymbol);
Shape shape = builder.build(s);
}
我不确定我是否理解正确,似乎很奇怪,还没有人提到这一点: Map dict=新的HashMap; dict.put'C,新的电路工厂; dict.put'R,新矩形工厂; 新三角工厂; ... ShapeFactory=dict.getsymbol; Shape=factory.createdata;
我不确定我是否理解正确,似乎很奇怪,还没有人提到这一点: Map dict=新的HashMap; dict.put'C,新的电路工厂; dict.put'R,新矩形工厂; 新三角工厂; ... ShapeFactory=dict.getsymbol; Shape=factory.createdata;
实际上,您可以使用多态性来避免if-else语句。因此,您可以创建实际执行这两项任务的对象,匹配直线并创建形状。因此,您可以使用如下代码
public class Program {
public static void main() throws FileNotFoundException {
Scanner file = new Scanner(new File("shapes.dat"));
while (file.hasNextLine()) {
String line = file.nextLine().trim();
Shape shape = new Matches(
new RectangleMatch(),
new TriangleMatch(),
new SquareMatch(),
new CircleMatch()
).map(line);
}
}
public interface ShapeMatch {
boolean matches(String line);
Shape shape(String line);
}
public static final class RectangleMatch implements ShapeMatch {
@Override
public boolean matches(String line) {
return line.startsWith("R");
}
@Override
public Shape shape(String line) {
String[] dimensions = line.substring(2).split(" ");
return new Rectangle(
Integer.parseInt(dimensions[0]),
Integer.parseInt(dimensions[1]),
Integer.parseInt(dimensions[2])
);
}
}
public static final class CircleMatch implements ShapeMatch {
@Override
public boolean matches(String line) {
return line.startsWith("C");
}
@Override
public Shape shape(String line) {
return new Circle(Integer.parseInt(line.substring(2, line.indexOf(" "))));
}
}
public interface ShapeMapping {
Shape map(String line);
}
public static final class Matches implements ShapeMapping {
private final Iterable<ShapeMatch> matches;
public Matches(ShapeMatch... matches) {
this(Arrays.asList(matches));
}
public Matches(Iterable<ShapeMatch> matches) {
this.matches = matches;
}
@Override
public Shape map(String line) {
for (ShapeMatch match : matches) {
if (match.matches(line)) {
return match.shape(line);
}
}
throw new RuntimeException("Invalid shape entry line.");
}
}
}
实际上,您可以使用多态性来避免if-else语句。因此,您可以创建实际执行这两项任务的对象,匹配直线并创建形状。因此,您可以使用如下代码
public class Program {
public static void main() throws FileNotFoundException {
Scanner file = new Scanner(new File("shapes.dat"));
while (file.hasNextLine()) {
String line = file.nextLine().trim();
Shape shape = new Matches(
new RectangleMatch(),
new TriangleMatch(),
new SquareMatch(),
new CircleMatch()
).map(line);
}
}
public interface ShapeMatch {
boolean matches(String line);
Shape shape(String line);
}
public static final class RectangleMatch implements ShapeMatch {
@Override
public boolean matches(String line) {
return line.startsWith("R");
}
@Override
public Shape shape(String line) {
String[] dimensions = line.substring(2).split(" ");
return new Rectangle(
Integer.parseInt(dimensions[0]),
Integer.parseInt(dimensions[1]),
Integer.parseInt(dimensions[2])
);
}
}
public static final class CircleMatch implements ShapeMatch {
@Override
public boolean matches(String line) {
return line.startsWith("C");
}
@Override
public Shape shape(String line) {
return new Circle(Integer.parseInt(line.substring(2, line.indexOf(" "))));
}
}
public interface ShapeMapping {
Shape map(String line);
}
public static final class Matches implements ShapeMapping {
private final Iterable<ShapeMatch> matches;
public Matches(ShapeMatch... matches) {
this(Arrays.asList(matches));
}
public Matches(Iterable<ShapeMatch> matches) {
this.matches = matches;
}
@Override
public Shape map(String line) {
for (ShapeMatch match : matches) {
if (match.matches(line)) {
return match.shape(line);
}
}
throw new RuntimeException("Invalid shape entry line.");
}
}
}
您想在运行时创建实例?@Ravi是的,没错。如果/switch有风险且容易出现错误,您可以尝试为每种类型的形状创建类创建新实例而不使用else,但如果您确实必须这样做,可能会有所帮助。您想在运行时创建实例吗?@Ravi是的,这是正确的。如果/switch有风险且容易出现错误,您可以尝试为每种类型的形状创建类创建一个新实例而不使用else,但如果您确实必须这样做,则可能会有所帮助。您命名三角形类的方式是任意的吗?为什么com.shape.Triangle与Triangle相反?@TiwaAina只是想让您知道,如果它驻留在某个包中,那么您应该使用完整的类名。@TiwaAina阅读JavaDoc的内容。@CardinalSystem哦,我明白了,我们需要类的完全限定名。您命名Triangle类的方式是任意的吗?为什么是com.shape.Triangle而不是Triangle?@TiwaAina只是想让你知道,如果它驻留在某个包中,那么你应该使用完整的类名。@TiwaAina阅读JavaDoc的内容。@CardinalSystem哦,我明白了,我们需要类的完全限定名。和你的想法相同,但我花时间解释了为什么要避免其他选择。我可能不会这么做:和你的想法一样,但我花时间解释了为什么要避免其他选择。我可能不会这么做: