1

I have followings classes (it's just a simplified example):

public abstract class Material {
    public abstract String name();
    /* ... */
}

public class Wood extends Material {
    @Override
    public String name() {
        return "<WOOD>";
    }
    /* ... */
}

public class Metal extends Material {
    @Override
    public String name() {
        return "{Metal}";
    }
    /* ... */
}

public class Car<T extends Material> {
    public void printName() {
        System.out.println(T.name()); // Here is the problem!
    }
    /* ... */
}

public class Main {
    public static void main(String[] args) {
        Car<Wood> myCar1 = new Car<Wood>();
        Car<Metal> myCar2 = new Car<Metal>();
        myCar1.printName();
        myCar1.printName();
    }
}

The problem is indicated in the code.

1
  • I don't think the question has anything to do with reflection.Please change the title name and tag. Commented Nov 18, 2010 at 12:07

6 Answers 6

3

This is probably how I would have implemented it. If it satisfactory or not for your situation, I can't tell.

enum Material {

    WOOD("<WOOD>"),
    METAL("{Metal}");

    String name;
    private Material(String name) {
        this.name = name;
    }
    public String toString() {
        return name;
    }
}

class Car {
    Material material;
    public Car(Material material) {
        this.material = material;
    }
    public void printName() {
        System.out.println(material);
    }
}

public class Main {
    public static void main(String[] args) {
        Car myCar1 = new Car(Material.WOOD);
        Car myCar2 = new Car(Material.METAL);
        myCar1.printName();
        myCar2.printName();
    }
}
Sign up to request clarification or add additional context in comments.

Comments

2

Here is one problem:

name is instance method ( not static ), but you are trying to call it as static.

This should fix it

public class Car<T extends Material> {
    public void printName( T material ) {
        System.out.println( material.name()); 
    }
    /* ... */
}

3 Comments

No that won't work... First of all you can't override static methods, so this doesn't make sense.
I really want the 'name' method was static. But if it can't then I have to remodel my design. Thanks so much.
But this won't work. static methods aren't virtual, so you'll always end up with Material.name() in this case.
1

The problem is that you're trying to call an instance method without having an instance of the object on which to call it.

Comments

1

There are a lot of misunderstanding in your question:

  1. name() is not a static function, therfore you need an instance of a material object to call it.
  2. even if name() were static, you cannot call a static method from a generic name.

A solution? Create a enumeration of material:

public enum Material {
    WOOD("wood"), 
    METAL("metal");

    private final String name;

    Material(String name) {
        this.name = name;
    }
}

And in the car class became:

public class Car {
    private final Material m;

    public Car(Material m) {
        this.m = m
    }

    public void printName() {
        System.out.println(m.name);
    }
    /* ... */
}

Comments

0

T defines the type, and the name() should be static to be called in that context. Also, consider:

public class Car<T extends Material> {
    protected T material;
    // initialize material in constructor or wherever you want.
    ....
    public void printName() {
        System.out.println(material.name()); // there is no problem
    }
    /* ... */
}

Comments

0

This will never work, since your 'T' is only a "compiler hint", and you can't access the class defined by T at runtime, unless you refer to it explicitly in your functions.

That's not how java generics work: when you compile your code, any reference to Wood and Metal is lost, and your 2 "Car" objects are identical.

Try this:

myCar1 = new Car<Wood>();
System.out.println(myCar1 instanceof Car<Metal>);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.