在泛型方法中使用构造函数参数实例化对象

Instantiate Object with constructor arguments in a generic method

我目前正在尝试编写一种方法,该方法 returns 一个新的泛型数组,其中填充了随机值的对象,但我正在努力创建对象。

假设我有一个 class Rectangle 和一个 class Cricle 它们都只能被初始化通过他们的构造函数并且缺少一个空的构造函数。使用泛型方法时是否可以访问这些示例 classes 的构造函数?

Rectangle.java

public class Rectangle
{
  private double width;
  private double height;
  private double area;

  public Rectangle( double width, double height )
  {
    this.width = width;
    this.height = height;
    this.area = width * height;
  }
  // Getter....
}

Circle.java

public class Circle
{
  private double area;
  private double radius;

  public Circle( double radius )
  {
    this.radius = radius;
    this.area = Math.PI * Math.pow( radius, 2 );
  }
  // Getter....
}

我希望能以某种方式解决:

ArrayFactory.java

public class ArrayFactory<T>
{

  @SuppressWarnings ( "unchecked")
  public T[] getArray( int size, int min, int max )
  {
    Random ran = new Random();
    double var1 = (ran.nextDouble() * max) - min;
    double var2 = (ran.nextDouble() * max) - min;

    T[] temp = (T[]) new Object[size];

    for ( int i = 0; i < t.length; i++ )
    {
      // this does obviously not work 
      // because the constructor of java.lang.Object takes no arguments
      temp[ i ] = (T) new Object(var1,var2);
    }
    return temp;
  }
}

这是没有希望的,因为 RectangleCircle 都没有共同的基础 class 或接口。泛型在这里帮不了你。

这看起来像继承 101 Shape 的例子。 (Animal 是另一个常见的。)

你可以这样做:

public interface Shape {
    double area();
    double perimeter();
}

public class Rectangle implements Shape {
    private double width;
    private double height;

    public Rectangle(double w, double h) {
        this.width = w;
        this.height = h;
    }

    public double area() { return w*h; }
    public double perimeter() { return 2.0*(w+h); }
}

public class ShapeFactory() { 
    public Shape createShape(double ... args) {
        if (args.length == 1) {
            return new Circle(args[0]);
        } else if (args.length == 2) { 
            return new Rectangle(args[0], args[1]);
        } else {
            throw new IllegalArgumentException("Wrong number of arguments");
        }
    }
}

本厂会"work",但数量有限。您无法区分具有两个 ctor 参数的形状(例如 RectangleSquareTriangleRhombus、3D 圆柱体等)对于那些您将拥有传递一个Class,除了可变数量的维度参数值,并使用instanceOf.

使用 instanceOf 通常表明您对多态性的使用被破坏了,但我认为在这种情况下它是可以接受的,只要它与工厂方法隔离即可。

您可以使用工厂 class 实现:

public interface ArrayFactory<T> {
    public T newElement();
    public T[] newArray(int size);
}

示例:

class RectangleArrayFactory implements ArrayFactory<Rectangle> {
    private final Random ran = new Random();
    private final int min;
    private final int max;

    public RectangleArrayFactory(int min, int max) {
        this.min = min;
        this.max = max;
    }

    @Override
    public Rectangle newElement() {
        double var1 = (ran.nextDouble() * max) - min;
        double var2 = (ran.nextDouble() * max) - min;
        return new Rectangle(var1, var2);
    }

    @Override
    public Rectangle[] newArray(int size) {
        return new Rectangle[size];
    }
}

要创建并填充一个数组,您可以这样做:

public <T> T[] newArray(ArrayFactory<T> fac, int size) {
    T[] result = fac.newArray(size);
    for (int i = 0; i < size; ++i) {
        result[i] = fac.newElement();
    }
    return result;
}