为什么在Java中使用泛型?它与重载有何不同?

为什么在Java中使用泛型?它与重载有何不同?,java,generics,Java,Generics,我想在Java中编写一个方法add(),它可以同时添加整数、字符串等。泛型将对我有所帮助 我无法理解泛型的最终目的。我很困惑 泛型与重载 public Integer add(Integer i, Integer j){return i+j;} public String add(String i, String j){return i+j;} public <T> T add(T i, T j){return i+j;} //this gives me error. public

我想在Java中编写一个方法
add()
,它可以同时添加整数、字符串等。泛型将对我有所帮助

我无法理解泛型的最终目的。我很困惑

泛型与重载

public Integer add(Integer i, Integer j){return i+j;}
public String add(String i, String j){return i+j;}
public <T> T add(T i, T j){return i+j;} //this gives me error.
public Integer add(整数i,整数j){return i+j;}
公共字符串add(stringi,stringj){returni+j;}
publictadd(ti,tj){returni+j;}//这给了我一个错误。
请把我弄出来

谢谢

我想用Java编写一个add()方法,它可以同时添加整数、字符串等。泛型可以帮助我

泛型主要在编译时用于类型安全

只能为外接程序集合指定一种类型

列表lst

将只接受字符串,没有字符串的超类没有子类[例如,如果存在]

泛型可能会有所帮助,这里的问题是
+
操作只针对java原语和
字符串定义,而不针对一般类型。在java中,我们不能重载运算符(例如C++中可以使用的)。
没有泛型的实用解决方案是:

public Integer add(Integer a, Integer b) { return a + b; }    // sum of a and b
public String add(String a, String b) { return a + b; }      // concatenate operation!
public MyType add(MyType a, MyType b) { return a.add(b); }   // requires add operation

泛型很好,因为如果操作得当,它可以让您概括您编写的一些代码。在编写软件时,您希望尽量减少不必要的代码,并尽可能多地重用代码


通过使用重载方法,您必须写出每个重载,而对于泛型,您只需要写一次。泛型在操作集合的情况下工作得很好,因为您对集合集执行了某些常见操作。在某些情况下,如果您希望使用一种更定制的方法来处理某些情况,那么您可能必须重载这些方法,但是如果您可以在多个地方使用泛型,那么我的目标是编写泛型

这正是泛型的要点。 您不希望实现一个可以接受一切的方法。坦率地说,您总是可以实现该方法

添加(对象对象对象)

并将整数、字符串、布尔值传递给它。。。但在大多数情况下,你不想这样做。方法必须处理参数,因此它应该知道参数的类型。这就是为什么如果要使接收字符串和整数的方法add实现2种方法的原因:

add(String s);
add(int i);
现在您无法将布尔值发送到add()方法:这样的方法根本不存在

您还可以实现泛型方法

void add(T arg)

并称之为:
this.add(“hello”)或<代码>此。添加(123)

在这种情况下,
this.add(123)导致编译错误

public Integer add(Integer i, Integer j){return i+j;}
public String add(String i, String j){return i+j;}
public <T> T add(T i, T j){return i+j;} //this gives me error.

但是,没有公共基类
XXXXX
支持我们在泛型方法(
+
)中要做的一切,因此泛型不能用来解决这个问题。

使用泛型接口的方法如何:

interface Adder<T> {
    T add(T first, T second);
}
接口加法器{
T加(T第一,T第二);
}
还有一个经理班:

public class AdderManager{

    public <T> AdderManager putAdder(final Class<T> clazz,
        final Adder<? extends T> adder){
        adders.put(clazz, adder);
        return this;
    }

    @SuppressWarnings("unchecked")
    public <T> Adder<T> getAdder(final Class<T> clazz){
        return (Adder<T>) adders.get(clazz);
    }

    private final Map<Class<?>, Adder<?>> adders =
        new HashMap<Class<?>, Adder<?>>();

}
公共类加法器管理器{
公共加法器管理器加法器(最后一节课,
最终加法器>(){
@凌驾
公共列表添加(第一个最终列表,第二个最终列表){
最终列表newList=newarraylist();
返回newList;
}
});
现在你可以使用这样的加法器:

String addedString = manager.getAdder(String.class).add("abc", "def");

@SuppressWarnings("unchecked") // this is necessary because of
                               // the generic <Integer> type
List<Integer> addedList = manager
                            .getAdder(List.class)
                            .add(
                                Arrays.asList(1,2,3),
                                Arrays.asList(4,5,6)
                             );
String addedString=manager.getAdder(String.class).add(“abc”,“def”);
@SuppressWarnings(“未选中”)//这是必要的,因为
//泛型
列表添加列表=管理器
.getAdder(List.class)
.添加(
数组。asList(1,2,3),
数组。asList(4,5,6)
);

java中的泛型只向字节码添加强制转换

代码将是相同的,除了铸造

因此,这两种结构:

List list1 = new ArrayList();
List<String list2 = new ArrayList<String>();
....
String string1 = (String) list1.get(0);
String string2 = list2.get(0);
List list1=new ArrayList();

列表< P>其他人已经指出了为什么这不起作用。让我只是补充一下,我认为你误解了java泛型是什么意思。也许你熟悉C++模板,或者是用C宏扩展,它们都类似于泛型,但却是一个非常不同的东西。 泛型实际上是关于类型安全和避免混乱的类型转换。你告诉编译器某个集合包含字符串,然后它知道你放入或取出的所有东西都必须是字符串。你可以在编译时检查你放入的东西,并在取出的东西上保存一些类型转换


它不会导致编译器根据类型生成不同的代码。泛型并不是避免编写“int”版本和“float”版本的简单方法同一个函数的版本,比如宏或C++模板,对你来说是可以的。你可以通过使用两个类实现相同的函数,但是使用一个函数,另一个使用浮点,但是你可以用没有泛型的面向对象技术来实现。如果你不能得到想要的不同的行为。r使用“非泛型”面向对象技术,那么你也不能使用泛型。

当你使用
整数i+Integer j
时,你实际上并不是在添加
整数
整数
不支持
+
运算符。它们会被解压到
整数
中,而不是直接添加为
整数
对象。你不能添加g通用对象,因为对象不支持
+
运算符。
字符串
是一种特殊情况,支持
+
。调用这两个示例的唯一原因是它们使用
+
运算符,这实际上是一个毫无意义的相似性,因为它做的事情完全不同用于字符串和整数。Name方法
final AdderManager manager = new AdderManager();
manager
.putAdder(String.class, new Adder<String>(){

    @Override
    public String add(final String first, final String second){
        return first.concat(second);
    }
})
.putAdder(Integer.class, new Adder<Integer>(){

    @Override
    public Integer add(final Integer first, final Integer second){
        return first + second;
    }
})
.putAdder(List.class, new Adder<List<?>>(){

    @Override
    public List<?> add(final List<?> first, final List<?> second){
        final List<Object> newList = new ArrayList<Object>();

        return newList;
        }
});
String addedString = manager.getAdder(String.class).add("abc", "def");

@SuppressWarnings("unchecked") // this is necessary because of
                               // the generic <Integer> type
List<Integer> addedList = manager
                            .getAdder(List.class)
                            .add(
                                Arrays.asList(1,2,3),
                                Arrays.asList(4,5,6)
                             );
List list1 = new ArrayList();
List<String list2 = new ArrayList<String>();
....
String string1 = (String) list1.get(0);
String string2 = list2.get(0);