【问题标题】:java generics with more than 2 parameters具有超过 2 个参数的 java 泛型
【发布时间】:2018-04-28 21:10:11
【问题描述】:

我有一个类测试,其中 K、V、T - 键、值、时间戳 我有一个接口 put(K key, V value, T timestamp)

我的hashmap初始化如下:

import java.util.*;
import java.lang.*;
import java.io.*;

class Test1<K,V,T> {

    private final HashMap<K, TreeMap<T, V>> map = new HashMap<K, TreeMap<T, V>>(); 
    private void put(K key, V value, T timeStamp) {

     }

    public void put(K key, V value){
         // Here it gives compiler error
        put(key, value, System.currentTimeMillis());
    }
}


/* Name of the class has to be "Main" only if the class is public. */
public class Ideone
{
    public static void main (String[] args) throws java.lang.Exception
    {
        Test1<Integer, Integer, Long> classInstance = new Test1<>();
        classInstance.put(10, 10);
    }
}

但是放在这里会给出编译器错误说明:

put(K, V, T) 不适用于参数 (Integer, Integer, Long)。

有人可以帮忙

【问题讨论】:

  • 你的put方法定义在哪里?
  • 代码对我来说工作正常
  • 无法复制:ideone.com/Ora2qr
  • @OliverCharlesworth 我已经编辑帖子给你确切的错误。
  • T 总是会是Long 时间戳吗?如果是这样,那么您不需要第三个泛型参数。只需让类签名具有KV 并使用LongV 初始化TreeMap

标签: java generics


【解决方案1】:

我建议的解决方案是声明你的类抽象,这样你就可以让子类来定义如何获取它们的时间戳:

public abstract class Test1<K,V,T> {

    private final HashMap<K, TreeMap<T, V>> map = new HashMap<>();

    private void put(K key, V value, T timeStamp) {
        // ...
    }

    public void put(K key, V value){
        // Here it no longer gives compiler error
        put(key, value, getCurrentTimestamp());
    }

    protected abstract T getCurrentTimestamp();
}

这允许T 的任何引用类型,包括LongInteger 或您可以想象的任何类型。任何想要使用该类的人都必须确定T 的类型以及生成T 类型的适当对象的方法。这是我使用Instant 对象的示例:

class Test1UsingInstant extends Test1<Integer, Integer, Instant> {

    @Override
    // declared return type needs to the same as supplied
    // as third type in Test1<Integer, Integer, Instant> above
    protected Instant getCurrentTimestamp() {

        // returned value needs to be of the declared return type
        // (auto-boxing will work, though)
        return Instant.now();
    }

}

然后可以像这样使用这个具体的子类:

        Test1UsingInstant instance = new Test1UsingInstant();
        instance.put(10, 10);

对两个参数put 的调用进入Test1 类,其中getCurrentTimestamp 被调用以获得Instant,该Instant 又作为第三个参数提供给三参数@987654335 @。

另一个例子:

public class Test1UsingLong extends Test1<Integer, Integer, Long> {

    @Override
    protected Long getCurrentTimestamp() {
        return System.currentTimeMillis();
    }

}

使用方法同第一个例子:

        Test1UsingLong instance = new Test1UsingLong();
        instance.put(10, 10);

我已经编译并运行了我的所有代码。

getCurrentTimestamp 也可以称为时间戳的工厂方法。换句话说,我使用的是Factory Method design pattern

【讨论】:

  • 这也行不通。尝试做同样的事情。编译错误:返回类型与getCurrentTimestamp()的抽象类实现不兼容。
  • 代码在我的电脑上编译并运行良好。我在代码中添加了几个关于所用类型要求的 cmets。请看一下,@Vishal。
猜你喜欢
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
  • 2017-10-06
  • 2010-12-18
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多