Java 泛型-使用此

Java 泛型-使用此,java,generics,Java,Generics,一个类有两个构造函数。参数化构造函数和非参数化构造函数。问题是我无法使用此(…)从另一个调用参数化的一个。但是,当我从其他地方尝试相同的调用时(比如main方法),它就可以工作了 这是密码 package com.test.generics; public class Key<T> { private T t; public Key(T t){ this.t = t; } publ

一个类有两个构造函数。参数化构造函数和非参数化构造函数。问题是我无法使用此(…)从另一个调用参数化的一个。但是,当我从其他地方尝试相同的调用时(比如main方法),它就可以工作了

这是密码

package com.test.generics;

    public class Key<T> {

        private T t;

        public Key(T t){
            this.t = t;
        }

        public T getKey(){
            return t;
        }
    }
package com.test.generics;
公开类密钥{
私人T;
公钥(T){
t=t;
}
公共T getKey(){
返回t;
}
}
然后

package com.test.generics;

    public class KeyValueObject<T> {
        private String value;
        private Key<T> key;

        public KeyValueObject(Key<T> k){
            key = k;
            value = "-1";
        }

        public KeyValueObject(String keyString){
            this(new Key<String>(keyString)); //Here is the problem, this says the Constructor KeyValueObject<T>(Key<String> k) is undefined
        }
        public static void main(String[] args) {
            Key<String> keyStr = new Key<String>("x");
            KeyValueObject<String> keyValObj = new KeyValueObject<String>(keyStr); //I try the same thing from main method and it works.
        }
    }
package com.test.generics;
公共类KeyValueObject{
私有字符串值;
私钥;
public KeyValueObject(键k){
key=k;
value=“-1”;
}
public KeyValueObject(字符串keyString){
this(new Key(keyString));//问题是,这表示构造函数KeyValueObject(Key k)未定义
}
公共静态void main(字符串[]args){
Key keyStr=新钥匙(“x”);
KeyValueObject keyValObj=新的KeyValueObject(keyStr);//我在main方法中尝试了同样的方法,它也能工作。
}
}
为什么编译器会说“构造函数KeyValueObject(键k)未定义”。我确实定义了构造函数KeyValueObject(键k)


同样在主要方法中,我也在做同样的事情。如果重载构造函数起作用,我可以使用
newkeyvalueobject(“x”)
编译器错误是正确的,因为代码不是类型安全的。 要了解原因,假设您写道:

KeyValueObject<Integer> kv = new KeyValueObject("not an Integer");
KeyValueObject kv=新的KeyValueObject(“非整数”);

上述操作将产生使用
Key
参数调用
KeyValueObject(Key)
的尝试,这显然是无效的。

编译器错误是正确的,因为代码不是类型安全的。 要了解原因,假设您写道:

KeyValueObject<Integer> kv = new KeyValueObject("not an Integer");
KeyValueObject kv=新的KeyValueObject(“非整数”);

上述操作将尝试使用
Key
参数调用
KeyValueObject(Key)
,这显然是无效的。

KeyValueObject
属性声明的类型:

private Key<T> key;
私钥;
与构造函数调用中的类型参数不同:

public KeyValueObject(String keyString){
    this(new Key<String>(keyString));
}
public KeyValueObject(字符串keyString){
此(新键(键串));
}
构造函数的泛型类型参数必须与属性的类型匹配:

public KeyValueObject(T t){
    this(new Key<T>(t));
}
公钥值对象(T){
此(新键(t));
}

KeyValueObject
属性声明的类型:

private Key<T> key;
私钥;
与构造函数调用中的类型参数不同:

public KeyValueObject(String keyString){
    this(new Key<String>(keyString));
}
public KeyValueObject(字符串keyString){
此(新键(键串));
}
构造函数的泛型类型参数必须与属性的类型匹配:

public KeyValueObject(T t){
    this(new Key<T>(t));
}
公钥值对象(T){
此(新键(t));
}

正如我在评论中所写,您可以这样做:

public class Program {
    public static void main(String[] args) {
        KeyValueObject<String> $0 = new KeyValueObject<>(new Key<>("x")); //old school
        KeyValueObject<String> $1 = new KeyValueObject<>("x"); //boxing constructor
        KeyValueObject<String> $2 = KeyValueObject.make("x"); //factory method
    }
}

class Key<T> {
    T key;

    public Key(T key){
        this.key = key;
    }

    public T getKey(){
        return key;
    }
}

class KeyValueObject<T> {
    //Solution 2: Create a factory method to handle the case `T` == `String`
    static KeyValueObject<String> make(String value) {
        return new KeyValueObject<>(value);
    }

    String value;
    Key<T> key;

    KeyValueObject(Key<T> key){
        this.key = key;
        this.value = "-1";
    }

    //Solution 1: Change `String` to `T`
    KeyValueObject(T key){
        this(new Key<>(key));
    }
}
公共类程序{
公共静态void main(字符串[]args){
KeyValueObject$0=新的KeyValueObject(新键(“x”);//老派
KeyValueObject$1=新的KeyValueObject(“x”);//装箱构造函数
KeyValueObject$2=KeyValueObject.make(“x”);//工厂方法
}
}
类密钥{
T键;
公钥(T密钥){
this.key=key;
}
公共T getKey(){
返回键;
}
}
类KeyValueObject{
//解决方案2:创建一个工厂方法来处理大小写`T`=`String`
静态KeyValueObject make(字符串值){
返回新的KeyValueObject(值);
}
字符串值;
钥匙;
KeyValueObject(键){
this.key=key;
this.value=“-1”;
}
//解决方案1:将'String'更改为'T'`
KeyValueObject(T键){
这个(新钥匙),;
}
}

正如我在评论中所写,您可以这样做:

public class Program {
    public static void main(String[] args) {
        KeyValueObject<String> $0 = new KeyValueObject<>(new Key<>("x")); //old school
        KeyValueObject<String> $1 = new KeyValueObject<>("x"); //boxing constructor
        KeyValueObject<String> $2 = KeyValueObject.make("x"); //factory method
    }
}

class Key<T> {
    T key;

    public Key(T key){
        this.key = key;
    }

    public T getKey(){
        return key;
    }
}

class KeyValueObject<T> {
    //Solution 2: Create a factory method to handle the case `T` == `String`
    static KeyValueObject<String> make(String value) {
        return new KeyValueObject<>(value);
    }

    String value;
    Key<T> key;

    KeyValueObject(Key<T> key){
        this.key = key;
        this.value = "-1";
    }

    //Solution 1: Change `String` to `T`
    KeyValueObject(T key){
        this(new Key<>(key));
    }
}
公共类程序{
公共静态void main(字符串[]args){
KeyValueObject$0=新的KeyValueObject(新键(“x”);//老派
KeyValueObject$1=新的KeyValueObject(“x”);//装箱构造函数
KeyValueObject$2=KeyValueObject.make(“x”);//工厂方法
}
}
类密钥{
T键;
公钥(T密钥){
this.key=key;
}
公共T getKey(){
返回键;
}
}
类KeyValueObject{
//解决方案2:创建一个工厂方法来处理大小写`T`=`String`
静态KeyValueObject make(字符串值){
返回新的KeyValueObject(值);
}
字符串值;
钥匙;
KeyValueObject(键){
this.key=key;
this.value=“-1”;
}
//解决方案1:将'String'更改为'T'`
KeyValueObject(T键){
这个(新钥匙),;
}
}
类型
不一定匹配
,因此错误有效。(可能会出现不安全的类型转换)

考虑实现如下工厂方法:

public static KeyValueObject<String> createKeyValueObject(final String keyString) {
    return new KeyValueObject<String>(new Key<String>(keyString));
}
公共静态KeyValueObject createKeyValueObject(最终字符串keyString){
返回新的KeyValueObject(新键(键串));
}
或者为了更好地利用通用可能性:

public KeyValueObject(T k) {
    this(new Key<T>(k));
}
公钥值对象(tk){
这个(新键(k));
}
类型
不一定匹配
,因此错误有效。(可能会出现不安全的类型转换)

考虑实现如下工厂方法:

public static KeyValueObject<String> createKeyValueObject(final String keyString) {
    return new KeyValueObject<String>(new Key<String>(keyString));
}
公共静态KeyValueObject createKeyValueObject(最终字符串keyString){
返回新的KeyValueObject(新键(键串));
}
或者为了更好地利用通用可能性:

public KeyValueObject(T k) {
    this(new Key<T>(k));
}
公钥值对象(tk){
这个(新键(k));
}

KeyValueObject
的第二个构造函数中放置
T
而不是
String
。或者,您可以添加一个工厂方法:
publicstatickeyvalueobjectmake(stringvalue){returnnew