Java泛型改成非泛型。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java泛型改成非泛型。相关的知识,希望对你有一定的参考价值。
这个是不是Java泛型
package pair;
public class Pair<T>
private T first;
private T second;
public Pair()
first = null;
second = null;
public Pair(T first,T second)
this.first = first;
this.second = second;
public T getFirst()
return first;
public T getSecond()
return second;
public void setFirst(T newValue)
first = newValue;
public void setSecond(T newValue)
second = newValue;
222222222222222222222222222222
这个是不是非泛型
import java.text.DecimalFormat;
public class Product
private String name;
private double price;
private static DecimalFormat money = new DecimalFormat("$0.00");
public Product()
name = " ";
price = 0.00;
public String toProductString()
return name + " costs " + money.format(price);
public Product(String n, double p)
name=n;
price=p;
public static void main(String args[])
System.out.println(
new Product("金币",578.2).toProductString());
看看有没有错
把泛型改成对应的非泛型
把非泛型改成对应的泛型
高手帮忙
答案让我满意 我分都给你
我是做实验报告。。。要有对应的泛型 和非泛型
我是做实验报告。。。要有对应的泛型 和非泛型
我是做实验报告。。。要有对应的泛型 和非泛型
我是做实验报告。。。要有对应的泛型 和非泛型
class Pair<T1, T2>
protected T1 first;
protected T2 second;
public Pair()
first = null;
second = null;
public Pair(T1 first, T2 second)
this.first = first;
this.second = second;
public T1 getFirst()
return first;
public T2 getSecond()
return second;
public void setFirst(T1 newValue)
first = newValue;
public void setSecond(T2 newValue)
second = newValue;
public class Product extends Pair<String, Double>
private static DecimalFormat money = new DecimalFormat("$0.00");
public Product()
public String toProductString()
return this.getFirst() + " costs " + money.format(this.getSecond());
public Product(String n, double p)
super(n, p);
public static void main(String args[])
System.out.println(
new Product("金币", 578.2).toProductString());
针对你这两个类,Pair类可以写成泛型,他只负责保存两个未知对象,但是你只写了一个泛型,而你实际调用又有两个泛型,所以帮你改成两个泛型了。你可以看到在Pair定义泛型为你Product省去很多代码。
至于你说的泛型到非泛型转换,这个说法没什么意思,既然出现泛型就有存在的意义,否者就不要用。你Pair类就相当与一个仓库,既然是仓库就要定义泛型了,如果有泛型就意味着告诉别人你可以装任何东西了,同时说明你对装入的东西类型不负责,人也可以,畜生也行。但是到了真正使用者就必须要明确一个类型给你了,这是他的义务,这就class Product extends Pair<String, Double>体现出来了。而Product类就是一个无泛型的了,他就必须明确String n, double p这两个别的不管了,实际上你用别的类型也没办法创建Product对象了,他就有局限性了。
所以泛型能用则用,不需要用那就别用了。 要非泛型你拿你自己的交吧,这年头学校的教育真是盲目! 参考技术A 第一个是泛型,第二个是普通的,至于改么,不需改的吧,一个泛型就可以囊括N个普通型了,有泛型就别用普通的 参考技术B ……都泛型好,怎么用都行。
为啥在存在非泛型时选择泛型方法?
【中文标题】为啥在存在非泛型时选择泛型方法?【英文标题】:Why is a generic method chosen when a non-generic exists?为什么在存在非泛型时选择泛型方法? 【发布时间】:2015-09-17 21:34:50 【问题描述】:下面的程序产生这个输出:
Foo<T> called
Process is terminated due to ***Exception.
所以,Foo(baz)
调用泛型 Foo<T>
,但 Bar(baz)
递归并且不调用Bar<T>
。
我使用 C# 5.0 和 Microsoft .NET。当非泛型方法是override
时,编译器似乎选择了泛型方法,而不是递归。
我在哪里可以找到这个规则的解释?(我猜到编译器在这两种情况下都会选择递归。)
这是整个程序:
using System;
namespace ConsoleApplication1
class Baz
abstract class Parent
public abstract void Foo(Baz baz);
class Child : Parent
void Bar<T>(T baz)
Console.WriteLine("Bar<T> called");
public void Bar(Baz baz)
Bar(baz);
void Foo<T>(T baz)
Console.WriteLine("Foo<T> called");
public override void Foo(Baz baz)
Foo(baz);
class Program
static void Main(string[] args)
var child = new Child();
child.Foo(null);
child.Bar(null);
Console.ReadLine();
【问题讨论】:
我喜欢将所有此类情况视为编译器创建者惩罚您使用继承的方式...... 似乎子类中的非覆盖方法优先于子类中的覆盖方法;它可能会将被覆盖的方法视为父方法的一部分。 【参考方案1】:根据 MSDN 文档,优先考虑未被覆盖的方法签名。由于 Foo 的非泛型版本被覆盖,它立即进入选择方法的优先级底部。一般来说,下一步是选择最具体的方法并执行它。对于 Bar 方法,Bar(Baz baz)
方法将始终是您的情况最具体的方法。
重载解析是一种用于选择最佳的编译时机制 函数成员调用给定的参数列表和一组 候选功能成员。过载分辨率选择功能 在 C# 中的以下不同上下文中调用的成员:
调用在调用表达式中命名的方法(第 7.5.5)。调用以对象创建表达式命名的实例构造函数(第 7.5.10.1 节)。 通过元素访问调用索引器访问器(第 7.5.6 节)。调用表达式中引用的预定义或用户定义的运算符 (第 7.2.3 节和第 7.2.4 节)。这些上下文中的每一个都定义了 一组候选函数成员和它自己的参数列表 独特的方式,如上面列出的部分中详细描述的那样。 为 例如,方法调用的候选集不 包括标记为覆盖的方法(第 7.3 节),以及基中的方法 如果派生类中的任何方法是 适用(第 7.5.5.1 节)。
MSDN Overload Resolution
我将我认为与您的问题相关的文字加粗。
Stack Overflow 上的另一个问题可能会有所帮助。它一般谈论方法解析。不涉及被覆盖的方法,但有助于填补一些我没有涉及的过程。
【讨论】:
不错,不用看msdn我就知道原因了!【参考方案2】:重载解析向上搜索继承链,在每个点查找定义的方法。
Child
定义了void Foo<T>(T baz)
,但没有定义void Foo(Baz baz)
,因此选择了void Foo<T>(T baz)
。
通常这是有道理的;在实际代码中,如果Foo<T>(T baz)
与基类中的Foo(Baz baz)
在传递Baz
时所做的工作不相似,那么您的设计会令人困惑,您应该选择一个新名称。
您可以使用public new void Foo(Baz baz)
或public new virtual void Foo(Baz baz)
来强制在Child
中定义覆盖(尽管这里需要在层次结构中设置一个中间步骤,以便抽象方法有一个实现)可以调用base.Foo(baz)
(调用基本实现)和/或Foo<Baz>(baz)
(调用通用版本)`,但最好避免这种技巧。
【讨论】:
【参考方案3】:也许它的行为就像你实现这样的东西时
void myMethod(long? l)
void myMethod(int? i)
使用null
调用它将使用int?
添加这个
void myMethod(short? i)
仍然使用null
调用它,代码将切换到short?
可能有内部订单/优先级正在执行?
现在有了你的代码,我给出这个只是为了说明让编译器决定和程序员决定(显式调用)之间的区别
这是通用的Baz
.method private hidebysig
instance void Bar<T> (
!!T baz
) cil managed
// Method begins at RVA 0x2060
// Code size 13 (0xd)
.maxstack 8
IL_0000: nop
IL_0001: ldstr "Bar<T> called"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: ret
// end of method Child::Bar
你的实现
public void Bar(Baz baz)
Bar(baz);
给这个
.method public hidebysig
instance void Bar (
class ConsoleApplication1.Baz baz
) cil managed
// Method begins at RVA 0x206e
// Code size 10 (0xa)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: call instance void ConsoleApplication1.Child::Bar(class ConsoleApplication1.Baz)
IL_0008: nop
IL_0009: ret
// end of method Child::Bar
这个
public void Bar(Baz baz)
Bar<Baz>(baz);
给这个
.method public hidebysig
instance void Bar (
class ConsoleApplication1.Baz baz
) cil managed
// Method begins at RVA 0x206e
// Code size 10 (0xa)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: call instance void ConsoleApplication1.Child::Bar<class ConsoleApplication1.Baz>(!!0)
IL_0008: nop
IL_0009: ret
// end of method Child::Bar
【讨论】:
以上是关于Java泛型改成非泛型。的主要内容,如果未能解决你的问题,请参考以下文章