使用泛型方法

时间:2018-04-06 12:20:16

标签: java generics constructor instance

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

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

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;
  }
}

2 个答案:

答案 0 :(得分:2)

这是没有希望的,因为RectangleCircle都不共享公共基类或接口。泛型无法帮助你。

这看起来像继承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");
        }
    }
}

这家工厂将工作&#34;但它有限。你不能区分具有两个ctor参数的形状(例如RectangleSquareTriangleRhombus,3D圆柱等。)对于那些你&# 39;除了可变数量的维度参数值之外,还必须传递Class,并使用instanceOf

使用instanceOf通常是一个死的赠品,你对多态性的使用被打破了,但我认为在这种情况下它是可以接受的,只要它与工厂方法隔离。

答案 1 :(得分:1)

您可以使用工厂类实现:

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;
}