-2

Following on from my last question here:

I have a class like so:

public class nVector<T extends nVector<?>> {

    int i;

    public T add(T a) {

    }

}

And want the following to occur:

public T add(T a) {
    T b = this.clone();
    b.i += a.i;
    return b;
}

However the instantiation of the Generic type T is not allowed. Yet I can easily include an instance of T in my arguments.

I'm doing this because I have multiple children of the T type that inherit all methods from nVector and act upon themselves in an 'enclosed environment'. (i.e. They only take their own type as an argument, not other children)

Any way to fix this? The issue is, is that I have to return something of type T, and not nVector<?>.

  • Is `T` supposed to be the element type? Why is it declared `T extends nVector>`? – user2357112 May 29 '17 at 03:22
  • Please include necessary context in the question itself, rather than just linking to other questions. For example, this question is missing the crucial context that this class is meant to be subclassed as `public class Child extends nvector`, and that `this` is intended to actually be an instance of `T`. – user2357112 May 29 '17 at 03:28
  • `public nVector>` won't compile due to a missing keyword. The type name is non-conformant. How is it that the element type of `NVector` is itself `NVector`? The wildcard should not be used. You want `public interface NVector>` or something like, assuming you actually mean for the type to work out similarly to how `Enum` and `Comparable` do. – Lew Bloch May 29 '17 at 03:32
  • @LewBloch Woops! I'm typing this on the run. Fixing now. –  May 29 '17 at 03:38
  • @user2357112 Following on from my previous question, I had to do so because of wildcard issues in Eclipse. It kept warning me to do so. –  May 29 '17 at 03:39
  • 3
    Unrelated: class names start UpperCase in Java. Always. – GhostCat May 29 '17 at 03:41
  • @GhostCat Yes. I'm using it in a **very** enclosed system that won't ever be touched. Children of the class follow the correct format: `Vector2, Vector3`, etc. –  May 29 '17 at 03:43
  • @user2357112 If your referring to the fact that I accidently omitted the `class` keyword, then `T` is the generic, and `class` is the type. –  May 29 '17 at 03:45
  • And all those are pretty nothing saying names. Btw: why don't you define a simple interface, having a getIntValue() method for example? Your design looks strange, you should consider explaining to us the underlying problem you intend to solve here. – GhostCat May 29 '17 at 03:48
  • @GhostCat It's simply being able to create a reference to the child class. I have a whole list of Vector functions that I wish to be ambiguous, that is that I can have *n* types of Vectors, and they all do the same thing. Except as for the `T` in the code, I want to only be able to refer to the specific child that inherits said functions. Its hard to explain. :O –  May 29 '17 at 07:12
  • Yeah well. Try to explain why you want to expose a *field* of that class like you do in your `add` function. That might be hard; because that design *smells* ;-) – GhostCat May 29 '17 at 07:14
  • @GhostCat As bad as it is, atleast I'm only using it for myself and I don't have a degree as of yet. ;) –  May 29 '17 at 09:26

1 Answers1

1

You can pass a Class<T> to the nVector constructor. And then use cls.newInstance(). Something like,

public class nVector<T extends nVector<?>> {
    Class<T> cls;
    int i; // <-- default value 0. Should probably be set in the constructor
           //     or with a setter method.
    public nVector(Class<T> cls) {
        this.cls = cls;
    }

    public T add(T a) {
        T b = null;
        try {
            b = cls.newInstance();
            b.i = this.i + a.i; // <-- equivalent, thx @LukeLee
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return b;
    }
}

Of course, if all you need is T to return - you could just return a;

Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • 1
    The OP is adding two numbers `this.i` and `a.i`. – xiaofeng.li May 29 '17 at 03:29
  • Beautiful! Thankyou. I can then set the `cls` variable from childrne. –  May 29 '17 at 03:42
  • Hey Elliot, quick question, I'm trying to check the type `T` with `instanceof`, in the format of `if (obj instanceof T) {}` however it throws an error. Is there any way I can perform the above check and successfully cast to type `T` if true? –  May 29 '17 at 09:27