Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 打开流的泛型内部类_Java_Generics - Fatal编程技术网

Java 打开流的泛型内部类

Java 打开流的泛型内部类,java,generics,Java,Generics,我想为不同类型的开放流创建一个通用的内部类。为此,我做了以下工作: private class StreamOpener<T1, T2> { StreamOpener(String fileName, T1 v1) { v1 = null; try { v1 = new T1(new T2(fileName)); } catch (FileNotFoundExce

我想为不同类型的开放流创建一个通用的内部类。为此,我做了以下工作:

private class StreamOpener<T1, T2>
{
    StreamOpener(String fileName, T1 v1)
    {
        v1 = null;

        try
        {
            v1 = new T1(new T2(fileName));
        }
        catch (FileNotFoundException e)
        {
            System.err.println("File " + fileName + " not found.  Exiting");
            System.exit(-1);
        }
        catch (Exception e)
        {
            System.err.println("Error on file " + fileName + "  Exiting");
            System.exit(-1);
        }
    }
}   
私有类StreamOpener
{
StreamOpener(字符串文件名,T1 v1)
{
v1=零;
尝试
{
v1=新T1(新T2(文件名));
}
catch(filenotfounde异常)
{
System.err.println(“文件”+文件名+“未找到。正在退出”);
系统退出(-1);
}
捕获(例外e)
{
System.err.println(“文件错误”+文件名+“退出”);
系统退出(-1);
}
}
}   
其思想是,例如,用于读取文本文件,T1可以是Scanner,T2可以是FileInputStream。类似地,对于编写文本文件,T1可以是PrintWriter,T2可以是FileOutputStream

但是,我在以下行中遇到编译错误: v1=新T1(新T2(文件名))


有出路吗?

您不能完全按照您发布的内容来做,因为在Java中,泛型不是。然而,您可以使用修改您的示例,尽管这相当难看。例如:

private class StreamOpener<T1, T2>
{
    T1 v1;

    StreamOpener(String fileName, Class<T1> t1Class, Class<T2> t2Class)
    {
        try
        {
            Constructor<T2> t2Constructor = t2Class.getConstructor(String.class);
            T2 v2 = t2Constructor.newInstance(fileName);
            Constructor<T1> t1Constructor = t1Class.getConstructor(t2Class);
            v1 = constructor.newInstance(v2);
        }
        catch (NoSuchMethodException|SecurityException|InstantiationException|IllegalAccessException|IllegalArgumentException|InvocationTargetException e) // yuck
        {
           System.err.println("Reflection error, fire your programmer");
           System.exit(-1);
        }
        catch (FileNotFoundException e)
        {
            System.err.println("File " + fileName + " not found.  Exiting");
            System.exit(-1);
        }
        catch (Exception e)
        {
            System.err.println("Error on file " + fileName + "  Exiting");
            System.exit(-1);
        }
    }
}   
私有类StreamOpener
{
T1-v1;
StreamOpener(字符串文件名、类t1Class、类t2Class)
{
尝试
{
构造函数t2Constructor=t2Class.getConstructor(String.class);
t2v2=t2Constructor.newInstance(文件名);
构造函数t1Constructor=t1Class.getConstructor(t2Class);
v1=构造函数.newInstance(v2);
}
catch(NoSuchMethodException | SecurityException |实例化Exception | IllegalAccessException | IllegalArgumentException | InvocationTargetException e)//yuck
{
System.err.println(“反射错误,解雇程序员”);
系统退出(-1);
}
catch(filenotfounde异常)
{
System.err.println(“文件”+文件名+“未找到。正在退出”);
系统退出(-1);
}
捕获(例外e)
{
System.err.println(“文件错误”+文件名+“退出”);
系统退出(-1);
}
}
}   
然而,上面的代码非常糟糕。相反,您可以将T1的创建委托给如下接口:

interface StreamCreator<T> {
    T open() throws Exception; // code smell
}
接口StreamCreator{
T open()引发异常;//代码气味
}
然后,您可以在需要对象时调用它。一个实现可能
返回新的扫描仪(新的输入流(文件名))
。另一个实现可以
返回新的PrintWriter(新文件输出流(文件名))
。由于它是一个功能接口,您可以在Java8中定义与lambdas内联的实现


另一方面,我正在努力弄明白你为什么要这么做。扫描仪和PrintWriter公开两个完全不同的接口。那么,创建一个可以以不同方式创建这两个函数的函数有什么用处呢?调用代码必须特定于扫描仪或PrintWriter,那么,为什么不使用两种不同的方法创建扫描仪或PrintWriter呢?

如果
T1
LocalDateTime
T2
ThreadPoolExecutor
?所有这些都会导致Java没有语法来限制类型的构造函数签名。您只需对InputStream进行操作如何然后OutputStream并将使用哪个实现的决策委托给调用类?不,没有真正的出路。你真的不能这么做。