Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.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
C# 在泛型类实例化上创建了多少实例?_C#_Java_Generics_Instantiation - Fatal编程技术网

C# 在泛型类实例化上创建了多少实例?

C# 在泛型类实例化上创建了多少实例?,c#,java,generics,instantiation,C#,Java,Generics,Instantiation,考虑这样一类: class Foo<T> { private T myField; public void Set(T x) { myField = x; } } class-Foo { 私人T myField; 公共无效集(TX) { myField=x; } } 然后用T等于int,bool(值类型)和String,列表来实例化它 实例化将如何创建以及它们的外观如何 我对Java和C感兴趣。 根据我所读的内容,Java将创建一个基本上是强制

考虑这样一类:

class Foo<T>
{
   private T myField;
   public void Set(T x)
   {
      myField = x;
   }
}
class-Foo
{
私人T myField;
公共无效集(TX)
{
myField=x;
}
}
然后用
T
等于
int
bool
(值类型)和
String
列表来实例化它

实例化将如何创建以及它们的外观如何

我对Java和C感兴趣。


根据我所读的内容,Java将创建一个基本上是强制转换的通用类,而在C中,
int
bool
将有两个类,加上
String
List
的单个类,因为它们是参考值(这是真的吗?静态字段呢?).

注意,这里我假设常规CLR-无AOT等

在IL层面:有一个定义是
Foo
;无论
T
,IL都是相同的(共享的)

在JIT级别:对所有(共享)引用类型参数和每个(单独)值类型参数进行一次JIT(每个通用参数)。因此
Foo
Foo
的JIT是共享的,而
Foo
Foo
的JIT是单独的


创建的对象/实例的数量与
newfoo(…)
调用(或
Activator.CreateInstance(…)
等)的数量相同。

注意这里我假设常规CLR-无AOT等

在IL层面:有一个定义是
Foo
;无论
T
,IL都是相同的(共享的)

在JIT级别:对所有(共享)引用类型参数和每个(单独)值类型参数进行一次JIT(每个通用参数)。因此
Foo
Foo
的JIT是共享的,而
Foo
Foo
的JIT是单独的


创建的对象/实例的数量与
newfoo(…)
调用(或
Activator.CreateInstance(…)
等)的数量相同。

在JVM中,只有一个类:由类型擦除产生的类


在CLR中,为类型参数的每个值构造一个闭合类型,每个值都有自己的静态字段的不同副本;在具有引用类型参数的封闭类型之间共享JIT代码是一种实现优化。因此,虽然
Foo
Foo
可能引用相同的JIT转换方法实现,但它们不是相同的类型,并且具有不同的静态字段。

在JVM中,只有一个类:由类型擦除产生的类


在CLR中,为类型参数的每个值构造一个闭合类型,每个值都有自己的静态字段的不同副本;在具有引用类型参数的封闭类型之间共享JIT代码是一种实现优化。因此,虽然
Foo
Foo
可能引用相同的JIT转换方法实现,但它们不是相同的类型,并且具有不同的静态字段。

Java泛型是通过“类型擦除”实现的

编译器创建一个类
Foo
,它本质上具有
Foo
将具有的代码。它不像C++模板,其中基于类型对新类进行实例化。编译的速度比C++版本快,但确实会阻止编译时发生一些优化。我相信这个系统的主要原理是希望保持与前泛型Java的兼容性

类型参数,例如
Foo
中的
整数
,仅在编译时用于在程序员试图传入
条时发出错误,并允许编译器假设返回
T
的函数将返回
T
,而在预泛型Java中,程序员必须强制转换结果。还值得注意的是,
Foo
的任何方法实际上都不会检查它们的参数是否为
Integer
s,除非程序员明确地写下这一点


至于静态字段,因为对于不同的专门化,只有一个
Foo
而不是单独的
Foo
s,所以类型变量是“非静态”的,试图声明类型为
T
的静态成员是没有意义的。在我的编译器上,它失败了,错误是“非静态类型变量T不能从静态上下文引用”。

Java泛型是通过“类型擦除”实现的

编译器创建一个类
Foo
,它本质上具有
Foo
将具有的代码。它不像C++模板,其中基于类型对新类进行实例化。编译的速度比C++版本快,但确实会阻止编译时发生一些优化。我相信这个系统的主要原理是希望保持与前泛型Java的兼容性

类型参数,例如
Foo
中的
整数
,仅在编译时用于在程序员试图传入
条时发出错误,并允许编译器假设返回
T
的函数将返回
T
,而在预泛型Java中,程序员必须强制转换结果。还值得注意的是,
Foo
的任何方法实际上都不会检查它们的参数是否为
Integer
s,除非程序员明确地写下这一点

至于静态字段,因为对于不同的专门化,只有一个
Foo
而不是单独的
Foo
s,所以类型变量是“非静态”的,试图声明类型为
T
的静态成员是没有意义的。在我的编译器上,它失败了,错误是“非静态类型变量T不能从静态上下文引用”。

Java
public class Foo<T>
{
    private static Object staticMember;

    public T getStaticMember() { 
        return (T) staticMember; 
    }

    private T instanceMember;

    public T getInstanceMember() {
        return instanceMember;
    }

    public Foo(T value)
    {
        if (staticMember == null) 
        {
            staticMember = value;
        }
        this.instanceMember = value;
    }        
}
Foo<Integer> foo = new Foo<Integer>(3);
System.out.println(foo.getStaticMember()); // >> 3
System.out.println(foo.getInstanceMember()); // >> 3
Foo foo = new Foo(3);
System.out.println(((Integer) foo.getInstanceMember()).toString()); // 3
System.out.println(((Integer) foo.getStaticMember()).toString()); // 3
Foo<Integer> foo1 = new Foo<Integer>(3);
Foo<String> foo2 = new Foo<String>("This is a string");
System.out.println(foo1.getInstanceMember()); // >> 3
System.out.println(foo2.getInstanceMember()); // >> This is a string
System.out.println(foo1.getStaticMember()); // >> 3
System.out.println(foo2.getStaticMember()); // Invalid cast exception
Foo foo1 = new Foo(3);
Foo foo2 = new Foo("This is a string");
System.out.println(((Integer) foo1.getInstanceMember()).toString()); // >> 3
System.out.println(((String) foo2.getInstanceMember()).toString()); 
// >> This is a string
System.out.println(((Integer) foo1.getStaticMember()).toString()); // >> 3
System.out.println(((String) foo2.getStaticMember()).toString()); 
// Invalid cast exception