`
悲剧了
  • 浏览: 143823 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

泛型理解上的一个问题

 
阅读更多
请帮忙解释下这个泛型问题,具体逻辑我都下在代码注释里面了
public class Test01 {
	public static void main(String[] args) throws Exception{
		ArrayList<Integer> arr1=new ArrayList<Integer>();
		ArrayList<String> arr2=new ArrayList<String>();
		//下面打印出来true,证明泛型只是编译器级别的一个东西,加载到内存还是一样的
		System.out.println(arr1.getClass()==arr2.getClass());
		//那么可以用跳过编译器用反射直接加入不通类型的东西,测试打印出"dodo"字符串
		arr1.add(55);
		arr1.getClass().getMethod("add", Object.class).invoke(arr1, "dodo");
		System.out.println(arr1.get(1));
		//既然如此那么下面这个也应该能正确打印,但是报异常异常为: java.lang.ClassCastException
		arr2.add("why");
		arr2.getClass().getMethod("add", Object.class).invoke(arr2, 33);
		System.out.println(arr2.get(1));
	}

}

分享到:
评论
18 楼 悲剧了 2010-11-08  
kala888 写道
悲剧了 写道
请帮忙解释下这个泛型问题,具体逻辑我都下在代码注释里面了
public class Test01 {
	public static void main(String[] args) throws Exception{
		ArrayList<Integer> arr1=new ArrayList<Integer>();
		ArrayList<String> arr2=new ArrayList<String>();
		//下面打印出来true,证明泛型只是编译器级别的一个东西,加载到内存还是一样的
		System.out.println(arr1.getClass()==arr2.getClass());
		//那么可以用跳过编译器用反射直接加入不通类型的东西,测试打印出"dodo"字符串
		arr1.add(55);
		arr1.getClass().getMethod("add", Object.class).invoke(arr1, "dodo");
		System.out.println(arr1.get(1));
		//既然如此那么下面这个也应该能正确打印,但是报异常异常为: java.lang.ClassCastException
		arr2.add("why");
		arr2.getClass().getMethod("add", Object.class).invoke(arr2, 33);
		System.out.println(arr2.get(1));
	}

}


// Decompiled by DJ v3.6.6.79 Copyright 2004 Atanas Neshkov  Date: 2010-11-08 9:27:39
// Home Page : http://members.fortunecity.com/neshkov/dj.html  - Check often for new version!
// Decompiler options: packimports(3) 
// Source File Name:   Test.java

package com.paic;

import java.io.PrintStream;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class Test
{

    public Test()
    {
    }

    public static void main(String args[])
        throws Exception
    {
        ArrayList arr1 = new ArrayList();
        ArrayList arr2 = new ArrayList();
        System.out.println(arr1.getClass() == arr2.getClass());
        arr1.add(Integer.valueOf(55));
        arr1.getClass().getMethod("add", new Class[] {
            java/lang/Object
        }).invoke(arr1, new Object[] {
            "dodo"
        });
        System.out.println(arr1.get(1));
        arr2.add("why");
        arr2.getClass().getMethod("add", new Class[] {
            java/lang/Object
        }).invoke(arr2, new Object[] {
            Integer.valueOf(33)
        });
        System.out.println((String)arr2.get(1));
    }
}

这个是你的代码反编译以后的代码。。。然后你的注释,就都得到解答了。。。

谢谢你的分析,我想问下:
System.out.println(arr1.get(1));这个没有强制转换(Integer)而

System.out.println((String)arr2.get(1));强制转化成了(String)具体原因能分析下吗?

不是加载到了内存后arr1和arr2的类字节码都相同吗?为什么会出现这个情况
17 楼 forestking 2010-11-08  
francis.xjl 写道
下面是我的猜想,仅供参考
再看了一下,我觉得应该是编译器进行了优化,跳过了一些步骤。
我们来读ArrayList的源码,它的add跟get方法是这样的:
public boolean add(E e) {
	ensureCapacity(size + 1);  // Increments modCount!!
	elementData[size++] = e;
	return true;
    }

public E get(int index) {
	RangeCheck(index);

	return (E) elementData[index];
    }

因此,你如果在ArrayList<String>运行时插入一个Integer类型的数据,由于范型只存在编译期的缘故,而且add方法没有对类型进行检查,因此,可以成功。但是,当你想取出这个对象时,就有一个问题:get方法中有一个强制转换,按照道理是会抛出异常的,如果在你原来的程序中加入这么一句试一下就知道了:
// add by francis.xjl
        System.out.println(arr1.get(1).getClass()); 

因此,其实抛出异常是正常的。

那为什么直接输出arr1.get(1)就可以呢?我估计是这样的:我们知道打印一个对象其实就是调用这个对象的toString()方法,而toString()方法是Object类型中的,因此,可能编译器觉得这里的强制转换没有必要,因此给省略了这个步骤。

因此,我觉得String类型的ArrayList会抛出异常可能是编译器考虑到其它的一些原因而没有进行优化。

当然,这仅仅是我的猜想,仅供参考


这个应该是正解。。。。
16 楼 luobin23628 2010-11-08  
利用thinking in java里的说法。。。
java里的泛型使用的是擦除机制。。 编译过后的类文件的泛型信息 已经被擦出了。。。 也就是说泛型只在编译期才存在。
因此 会有 arr1.getClass()==arr2.getClass()) 在运行期 arr1和arr2都ArrayList类型的
15 楼 pengliren 2010-11-08  
泛型只是在编译的时候类型检测,你可以用反射添加测试测试
14 楼 Kensai 2010-11-08  
francis.xjl 写道
bill.end 写道
kala888 写道
悲剧了 写道
请帮忙解释下这个泛型问题,具体逻辑我都下在代码注释里面了
public class Test01 {
	public static void main(String[] args) throws Exception{
		ArrayList<Integer> arr1=new ArrayList<Integer>();
		ArrayList<String> arr2=new ArrayList<String>();
		//下面打印出来true,证明泛型只是编译器级别的一个东西,加载到内存还是一样的
		System.out.println(arr1.getClass()==arr2.getClass());
		//那么可以用跳过编译器用反射直接加入不通类型的东西,测试打印出"dodo"字符串
		arr1.add(55);
		arr1.getClass().getMethod("add", Object.class).invoke(arr1, "dodo");
		System.out.println(arr1.get(1));
		//既然如此那么下面这个也应该能正确打印,但是报异常异常为: java.lang.ClassCastException
		arr2.add("why");
		arr2.getClass().getMethod("add", Object.class).invoke(arr2, 33);
		System.out.println(arr2.get(1));
	}

}


// Decompiled by DJ v3.6.6.79 Copyright 2004 Atanas Neshkov  Date: 2010-11-08 9:27:39
// Home Page : http://members.fortunecity.com/neshkov/dj.html  - Check often for new version!
// Decompiler options: packimports(3) 
// Source File Name:   Test.java

package com.paic;

import java.io.PrintStream;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class Test
{

    public Test()
    {
    }

    public static void main(String args[])
        throws Exception
    {
        ArrayList arr1 = new ArrayList();
        ArrayList arr2 = new ArrayList();
        System.out.println(arr1.getClass() == arr2.getClass());
        arr1.add(Integer.valueOf(55));
        arr1.getClass().getMethod("add", new Class[] {
            java/lang/Object
        }).invoke(arr1, new Object[] {
            "dodo"
        });
        System.out.println(arr1.get(1));
        arr2.add("why");
        arr2.getClass().getMethod("add", new Class[] {
            java/lang/Object
        }).invoke(arr2, new Object[] {
            Integer.valueOf(33)
        });
        System.out.println((String)arr2.get(1));
    }
}

这个是你的代码反编译以后的代码。。。然后你的注释,就都得到解答了。。。

也可以在 System.out.println()处按F3,
System.out.println(arr1.get(1));   进入的是PrintStream.println(Object x)
System.out.println(arr2.get(1));   进入的是PrintStream.println(String x)
这样看明白了么,泛型虽然是编译期时使用,但不是对运行期没有影响


很好理解了~~~
问一下,代码反编译是怎么用的?用什么工具?eclipse有对应的插件么?

这个仍然只是结果阿,为什么会这样还是没解决撒。。
13 楼 Kensai 2010-11-08  

楼主3个问题:
Q1.下面打印出来true,证明泛型只是编译器级别的一个东西,加载到内存还是一样的 
        System.out.println(arr1.getClass()==arr2.getClass()); 
因为java泛型是擦除的,泛型在编译时信息就掉了,编译器看到的类似ArrayList<Object>。所以这两个对象比较类相等。

Q2.那么可以用跳过编译器用反射直接加入不通类型的东西,测试打印出"dodo"字符串 
        arr1.add(55); 
        arr1.getClass().getMethod("add", Object.class).invoke(arr1, "dodo"); 
        System.out.println(arr1.get(1));

Q1里面的说的泛型擦除,在这里就是一个证明。在代码中arr1是 ArrayList<Integer>类型,但是用反射去找的时候,编译器已经把泛型擦除了。所以他的类型是ArrayList<Object>。这也就是为什么只能找到add(Object o)而不是add(Integer i)这个方法的原因了。
之所以没出错,是因为反射是运行时进行的,类型检查是编译时的。这段代码已经跳过了编译时类型检查,在运行时把String插入了没有泛型的List arr1中。

Q3既然如此那么下面这个也应该能正确打印,但是报异常异常为: java.lang.ClassCastException
这个具体原因不知到,我估计只是在处理基本类型wrapper和正常对象时,类型检查不一样。如果加上getClass()都会报错。这个问题带高人来解答了。
12 楼 francis.xjl 2010-11-08  
bill.end 写道
kala888 写道
悲剧了 写道
请帮忙解释下这个泛型问题,具体逻辑我都下在代码注释里面了
public class Test01 {
	public static void main(String[] args) throws Exception{
		ArrayList<Integer> arr1=new ArrayList<Integer>();
		ArrayList<String> arr2=new ArrayList<String>();
		//下面打印出来true,证明泛型只是编译器级别的一个东西,加载到内存还是一样的
		System.out.println(arr1.getClass()==arr2.getClass());
		//那么可以用跳过编译器用反射直接加入不通类型的东西,测试打印出"dodo"字符串
		arr1.add(55);
		arr1.getClass().getMethod("add", Object.class).invoke(arr1, "dodo");
		System.out.println(arr1.get(1));
		//既然如此那么下面这个也应该能正确打印,但是报异常异常为: java.lang.ClassCastException
		arr2.add("why");
		arr2.getClass().getMethod("add", Object.class).invoke(arr2, 33);
		System.out.println(arr2.get(1));
	}

}


// Decompiled by DJ v3.6.6.79 Copyright 2004 Atanas Neshkov  Date: 2010-11-08 9:27:39
// Home Page : http://members.fortunecity.com/neshkov/dj.html  - Check often for new version!
// Decompiler options: packimports(3) 
// Source File Name:   Test.java

package com.paic;

import java.io.PrintStream;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class Test
{

    public Test()
    {
    }

    public static void main(String args[])
        throws Exception
    {
        ArrayList arr1 = new ArrayList();
        ArrayList arr2 = new ArrayList();
        System.out.println(arr1.getClass() == arr2.getClass());
        arr1.add(Integer.valueOf(55));
        arr1.getClass().getMethod("add", new Class[] {
            java/lang/Object
        }).invoke(arr1, new Object[] {
            "dodo"
        });
        System.out.println(arr1.get(1));
        arr2.add("why");
        arr2.getClass().getMethod("add", new Class[] {
            java/lang/Object
        }).invoke(arr2, new Object[] {
            Integer.valueOf(33)
        });
        System.out.println((String)arr2.get(1));
    }
}

这个是你的代码反编译以后的代码。。。然后你的注释,就都得到解答了。。。

也可以在 System.out.println()处按F3,
System.out.println(arr1.get(1));   进入的是PrintStream.println(Object x)
System.out.println(arr2.get(1));   进入的是PrintStream.println(String x)
这样看明白了么,泛型虽然是编译期时使用,但不是对运行期没有影响


很好理解了~~~
问一下,代码反编译是怎么用的?用什么工具?eclipse有对应的插件么?
11 楼 madbluesky 2010-11-08  
编译器可以根据范型做优化的,答案楼上2位说的很清楚了。
ArrayList<String> arr2 = new ArrayList<String>();  
替换成
ArrayList<TestBean> arr2 = new ArrayList<TestBean>();  
将不会抛异常
10 楼 bill.end 2010-11-08  
kala888 写道
悲剧了 写道
请帮忙解释下这个泛型问题,具体逻辑我都下在代码注释里面了
public class Test01 {
	public static void main(String[] args) throws Exception{
		ArrayList<Integer> arr1=new ArrayList<Integer>();
		ArrayList<String> arr2=new ArrayList<String>();
		//下面打印出来true,证明泛型只是编译器级别的一个东西,加载到内存还是一样的
		System.out.println(arr1.getClass()==arr2.getClass());
		//那么可以用跳过编译器用反射直接加入不通类型的东西,测试打印出"dodo"字符串
		arr1.add(55);
		arr1.getClass().getMethod("add", Object.class).invoke(arr1, "dodo");
		System.out.println(arr1.get(1));
		//既然如此那么下面这个也应该能正确打印,但是报异常异常为: java.lang.ClassCastException
		arr2.add("why");
		arr2.getClass().getMethod("add", Object.class).invoke(arr2, 33);
		System.out.println(arr2.get(1));
	}

}


// Decompiled by DJ v3.6.6.79 Copyright 2004 Atanas Neshkov  Date: 2010-11-08 9:27:39
// Home Page : http://members.fortunecity.com/neshkov/dj.html  - Check often for new version!
// Decompiler options: packimports(3) 
// Source File Name:   Test.java

package com.paic;

import java.io.PrintStream;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class Test
{

    public Test()
    {
    }

    public static void main(String args[])
        throws Exception
    {
        ArrayList arr1 = new ArrayList();
        ArrayList arr2 = new ArrayList();
        System.out.println(arr1.getClass() == arr2.getClass());
        arr1.add(Integer.valueOf(55));
        arr1.getClass().getMethod("add", new Class[] {
            java/lang/Object
        }).invoke(arr1, new Object[] {
            "dodo"
        });
        System.out.println(arr1.get(1));
        arr2.add("why");
        arr2.getClass().getMethod("add", new Class[] {
            java/lang/Object
        }).invoke(arr2, new Object[] {
            Integer.valueOf(33)
        });
        System.out.println((String)arr2.get(1));
    }
}

这个是你的代码反编译以后的代码。。。然后你的注释,就都得到解答了。。。

也可以在 System.out.println()处按F3,
System.out.println(arr1.get(1));   进入的是PrintStream.println(Object x)
System.out.println(arr2.get(1));   进入的是PrintStream.println(String x)
这样看明白了么,泛型虽然是编译期时使用,但不是对运行期没有影响
9 楼 kala888 2010-11-08  
悲剧了 写道
请帮忙解释下这个泛型问题,具体逻辑我都下在代码注释里面了
public class Test01 {
	public static void main(String[] args) throws Exception{
		ArrayList<Integer> arr1=new ArrayList<Integer>();
		ArrayList<String> arr2=new ArrayList<String>();
		//下面打印出来true,证明泛型只是编译器级别的一个东西,加载到内存还是一样的
		System.out.println(arr1.getClass()==arr2.getClass());
		//那么可以用跳过编译器用反射直接加入不通类型的东西,测试打印出"dodo"字符串
		arr1.add(55);
		arr1.getClass().getMethod("add", Object.class).invoke(arr1, "dodo");
		System.out.println(arr1.get(1));
		//既然如此那么下面这个也应该能正确打印,但是报异常异常为: java.lang.ClassCastException
		arr2.add("why");
		arr2.getClass().getMethod("add", Object.class).invoke(arr2, 33);
		System.out.println(arr2.get(1));
	}

}


// Decompiled by DJ v3.6.6.79 Copyright 2004 Atanas Neshkov  Date: 2010-11-08 9:27:39
// Home Page : http://members.fortunecity.com/neshkov/dj.html  - Check often for new version!
// Decompiler options: packimports(3) 
// Source File Name:   Test.java

package com.paic;

import java.io.PrintStream;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class Test
{

    public Test()
    {
    }

    public static void main(String args[])
        throws Exception
    {
        ArrayList arr1 = new ArrayList();
        ArrayList arr2 = new ArrayList();
        System.out.println(arr1.getClass() == arr2.getClass());
        arr1.add(Integer.valueOf(55));
        arr1.getClass().getMethod("add", new Class[] {
            java/lang/Object
        }).invoke(arr1, new Object[] {
            "dodo"
        });
        System.out.println(arr1.get(1));
        arr2.add("why");
        arr2.getClass().getMethod("add", new Class[] {
            java/lang/Object
        }).invoke(arr2, new Object[] {
            Integer.valueOf(33)
        });
        System.out.println((String)arr2.get(1));
    }
}

这个是你的代码反编译以后的代码。。。然后你的注释,就都得到解答了。。。
8 楼 godtiger 2010-11-08  
你假如的是基本类型 而不是封装类
7 楼 fishescape 2010-11-08  
qianhd 写道
你们的瞎猜真没创意

改成 ArrayList arr2=new ArrayList<String>();  

就不会有异常
至于为什么 回去慢慢想



那为什么arr1没问题?
6 楼 qianhd 2010-11-08  
你们的瞎猜真没创意

改成 ArrayList arr2=new ArrayList<String>();  

就不会有异常
至于为什么 回去慢慢想
5 楼 francis.xjl 2010-11-08  
下面是我的猜想,仅供参考
再看了一下,我觉得应该是编译器进行了优化,跳过了一些步骤。
我们来读ArrayList的源码,它的add跟get方法是这样的:
public boolean add(E e) {
	ensureCapacity(size + 1);  // Increments modCount!!
	elementData[size++] = e;
	return true;
    }

public E get(int index) {
	RangeCheck(index);

	return (E) elementData[index];
    }

因此,你如果在ArrayList<String>运行时插入一个Integer类型的数据,由于范型只存在编译期的缘故,而且add方法没有对类型进行检查,因此,可以成功。但是,当你想取出这个对象时,就有一个问题:get方法中有一个强制转换,按照道理是会抛出异常的,如果在你原来的程序中加入这么一句试一下就知道了:
// add by francis.xjl
        System.out.println(arr1.get(1).getClass()); 

因此,其实抛出异常是正常的。

那为什么直接输出arr1.get(1)就可以呢?我估计是这样的:我们知道打印一个对象其实就是调用这个对象的toString()方法,而toString()方法是Object类型中的,因此,可能编译器觉得这里的强制转换没有必要,因此给省略了这个步骤。

因此,我觉得String类型的ArrayList会抛出异常可能是编译器考虑到其它的一些原因而没有进行优化。

当然,这仅仅是我的猜想,仅供参考
4 楼 悲剧了 2010-11-07  
wangzh1118 写道
你可以定义其它number类型的加入String 都没有问题。可能原因就是string属于引用类型,内存地址保存到int或long类型数组就没问题,反过来自然不行


但是不管泛型指定为何种类型,他们加载到内存中的时候都是一种类型,我的帖子中arr1.getClass()==arr2.getClass()测试了这个,所以在通过编译器后他们在内存中操作都是当做一个对象来对待的,number下面的类型也会自动装箱.
3 楼 wangzh1118 2010-11-07  
你可以定义其它number类型的加入String 都没有问题。可能原因就是string属于引用类型,内存地址保存到int或long类型数组就没问题,反过来自然不行
2 楼 悲剧了 2010-11-07  
francis.xjl 写道
我试了一下,自定义的类型也是可以的:

public class OO {
	@Override
	public String toString() {
		return super.toString();
	}
	
	public static void main(String[]args) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		
        ArrayList<OO> arr3 = new ArrayList<OO>();
        arr3.add(new OO());
        //arr3.getClass().getMethod("add", Object.class).invoke(arr3, "dodo"); //correct
        //arr3.getClass().getMethod("add", Object.class).invoke(arr3, 33); //correct
        arr3.getClass().getMethod("add", Object.class).invoke(arr3, new OO()); //correct
        System.out.println(arr3.get(1));
	}
}


我猜:有可能是编译器对String类型的ArrayList进行了优化??

不是这个问题,第一个元素和第二个元素加的都是一样的,我的意思是可以通过反射这种方式加入另外一种类型,比如你定义的泛型为OO,那么arr3.getClass().getMethod("add", Object.class).invoke(arr3, "why");
加入String类型的一个对象.

你取值时候会不会报异常呢?

我的代码是说:定义int型的泛型容器通过反射加入String类型的对象,然后get它,没问题
但是如果定义String型的泛型,通过反射加入int型的对象,就有问题了,报转换异常.....
1 楼 francis.xjl 2010-11-07  
我试了一下,自定义的类型也是可以的:

public class OO {
	@Override
	public String toString() {
		return super.toString();
	}
	
	public static void main(String[]args) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		
        ArrayList<OO> arr3 = new ArrayList<OO>();
        arr3.add(new OO());
        //arr3.getClass().getMethod("add", Object.class).invoke(arr3, "dodo"); //correct
        //arr3.getClass().getMethod("add", Object.class).invoke(arr3, 33); //correct
        arr3.getClass().getMethod("add", Object.class).invoke(arr3, new OO()); //correct
        System.out.println(arr3.get(1));
	}
}


我猜:有可能是编译器对String类型的ArrayList进行了优化??

相关推荐

    C#泛型类、泛型方法、泛型接口、泛型委托的实例

    泛型类是具有一个或多个类型参数的类。类型参数是在定义类时使用的占位符,实际的类型在创建类的实例时指定。例如,我们可以创建一个名为`GenericContainer&lt;T&gt;`的泛型类,其中`T`就是类型参数。这个类可以存储任何...

    C#泛型学习和理解代码示例

    C#泛型是.NET框架中的一个强大特性,它允许我们创建可重用的类型,这些类型可以在多种数据类型上工作,而无需重复编写相同代码。泛型的主要目标是提高代码的类型安全性和性能,同时减少类型转换的需要。在本文中,...

    java 带两个类型参数的泛型

    当我们谈论“java带两个类型参数的泛型”时,这意味着我们正在处理一个泛型类或泛型方法,它们接受不止一个类型作为参数。这样的设计可以让我们在不同数据类型之间建立更复杂的关联,同时保持类型安全。 首先,让...

    JVM如何理解Java泛型类.doc

    为了理解JVM如何处理泛型,我们需要了解一个重要的概念:“类型擦除”(Type Erasure)。类型擦除是指编译器在编译过程中去除所有泛型信息的过程。这一过程使得JVM不必直接支持泛型,因为所有泛型信息在编译后都被...

    java 一个关于泛型的简单例子

    此外,文件名`Java.jpg`可能表示的是一个与这个泛型例子相关的图片,可能是一个截图或者示意图,用于帮助理解泛型的概念或者`MyFirstGeneric`类的结构和用法。在实际学习过程中,视觉辅助工具往往能够帮助我们更好地...

    C# 泛型集合 C#初学者的一个适用案例

    综上所述,理解和熟练运用C#中的泛型集合对于任何C#初学者来说都是至关重要的。通过掌握List、Dictionary, TValue&gt;等泛型集合的使用,以及类型约束和泛型接口的概念,开发者能够编写出更安全、高效且易于维护的代码...

    C#泛型C#泛型C#泛型

    这个声明定义了一个泛型类 List,其中 T 是一个类型参数。这个泛型类可以实例化为不同的类型,例如 List、List&lt;string&gt; 等。 2. 类型参数 类型参数是一个简单的标识符,它指示了用来创建一个构造类型的类型参数的...

    重新理解Java泛型

    Java泛型是Java编程语言中的一个重要特性,它允许在类、接口和方法中使用类型参数,从而提高了代码的类型安全性和可复用性。本文旨在深入解析Java泛型的各个方面,帮助开发者形成全面、清晰的理解。 1. **泛型基础*...

    C# 泛型深入理解介绍

    泛型是C#编程语言中的一个重要特性,自C# 2.0版本开始引入,它极大地提升了代码的重用性和效率。本专题将深入探讨泛型的原理和优势,以及如何利用它们来优化代码。 首先,泛型允许我们在定义类、接口、委托和结构时...

    泛型java的泛型知识,非常有用

    例如,可以定义一个泛型方法,使其能接受不同类型的参数并返回不同类型的值。 9. **类型推断** - 自JDK 7起,Java引入了类型推断,允许在某些情况下省略类型参数,编译器会根据上下文自动推断类型。 理解并熟练...

    java泛型指南 经典

    泛型类允许我们在定义类时指定一个或多个类型参数。例如,我们可以定义一个简单的泛型类 `Box`: ```java public class Box&lt;T&gt; { private T item; public void setItem(T item) { this.item = item; } public...

    C#泛型,非泛型实现枚举

    例如,`List&lt;T&gt;`就是一个泛型类,其中`T`代表一个未指定的类型,实际使用时可以是整型、字符串或其他自定义类型。 当我们想要在泛型中实现枚举功能时,可能的场景是在一个集合中存储一组特定类型的枚举值。例如,...

    3个泛型项目源码.rar

    这个"3个泛型项目源码.rar"压缩包包含的三个项目,无疑为学习和理解泛型在实际项目中的应用提供了宝贵的资源。 泛型是C# 2.0引入的新特性,它允许开发者创建可以操作多种数据类型的类、接口和方法。这样做的好处...

    泛型用在类和方法上的写法

    泛型是Java编程语言中的一个重要特性,它引入了类型安全的概念,使得在编译时就能检查类型错误,而不是等到运行时。在类和方法上使用泛型,可以增强代码的可读性和复用性,避免类型转换的繁琐,并且提高了程序的效率...

    Jdk15泛型的实现

    例如,如果一个泛型类声明了类型参数`T extends Comparable&lt;T&gt;`,那么`T`必须是一个实现了`Comparable`接口的类型。这确保了使用该泛型类时,其内部操作能够正确地进行比较和排序。 自定义泛型类或算法时,开发者...

    VC++ 2005:泛型编程

    泛型编程的核心思想是参数化类型,即将数据类型作为一个参数传递给代码,使得代码能够适应不同类型的输入。 C++/CLI支持两种泛型机制:编译时泛型(基于ISO-C++模板)和运行时泛型(基于CLI泛型)。编译时泛型类似...

    泛型封装.rar

    在C#编程中,泛型是一种强大的特性,它允许我们创建可重用的类型安全的代码,能够处理多种数据类型。"泛型封装.rar"这个...通过深入研究这个例子,开发者可以更好地理解和掌握C#中的泛型技术,提升代码质量和效率。

Global site tag (gtag.js) - Google Analytics