Java中标记的含义是什么?
从www.JavaPractices.com复制的此代码中标记的含义是什么? 当我用更常规的用于generics类型的
替换它时,它无法编译。 (错误:T无法解析为某种类型。)为什么?
// occurs 3 times in the entire program. When it is replaced with the // program no longer compiles. void activateAlarmThenStop() { Runnable myPeriodicTask = new PeriodicTask(); ScheduledFuture soundAlarmFuture = this.executorService.scheduleWithFixedDelay(myPeriodicTask, startT, period, TimeUnit.SECONDS ); Runnable stopAlarm = new StopAlarmTask(soundAlarmFuture); this.executorService.schedule(stopAlarm, stopT, TimeUnit.SECONDS); } private final class StopAlarmTask implements Runnable { StopAlarmTask(ScheduledFuture aSchedFuture) { fSchedFuture = aSchedFuture; } public void run() { CConsole.pw.println("Stopping alarm."); fSchedFuture.cancel(doNotInterruptIfRunningFlag); executorService.shutdown(); } private ScheduledFuture fSchedFuture; }
编辑:当然,当我们使用类似generics类型标记时,它必须出现在类声明中。 这里在类声明中没有
也没有
,但它仍然可以编译并正常运行。
它无法编译,因为您的类不是通用的(也没有任何方法)。 在这个特定的例子中,joker(?)意味着ScheduledFuture可以被任何东西参数化。
有时,如果您在内部使用另一个generics类并且您不知道将使用的确切类型,那么将整个类设为通用是没有意义的。 在此示例中,您有三个选项:
- 使StopAlarmTask通用(在这种情况下没有意义)
- 在ScheduledFuture中使用具体类型,但它只是一种可能的结果类型,例如String或Integer
- 使用通配符(
< ? >
) – 它允许通过FutureResult(String,Integer,您的自定义类)检索任何内容。 您还可以将可能的generics类型的范围缩小到某些子类,例如ScheduledGeneric< ? extends MyObject >
ScheduledGeneric< ? extends MyObject >
或超类:ScheduledGeneric< ? super MyObject >
ScheduledGeneric< ? super MyObject >
这是在类型参数中使用通配符的示例。 即一般类型。 通配符参数化类型是generics类型的实例化,其中至少一个类型参数是通配符。 通配符参数化类型的示例是Collection>
, List extends Number>
List extends Number>
, Comparator super String>
Comparator super String>
和Pair
。
通配符参数化类型表示包括generics类型的具体实例的类型族。 正在使用的通配符类型决定了哪些具体参数化类型属于该族。
这是Generic Type
…通常我们将String,Object或任何其他对象设置为generics类型……但是在这里它们使它变得通用。 和generics类型代表它可以store or hold
的值。 它通常用于Collections
..
那么两者之间没有太大的区别.. – 采取所有类型的对象
-is also called `formal type parameter` makes use of what ever type of object you pass in .. for instance you can do this with and not with > public class Box { private T t; // T stands for "Type" public void add(T t) { this.t = t; } public T get() { return t; } }
有关更多信息,请参阅http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf和http://download.oracle.com/javase/tutorial/java/generics/gentypes.html
括号中的字母如
将是一个类型参数。 你会说class StopAlarmTask
意味着你正在使用类型T
参数化类型StopAlarmTask
。 类型参数T
将成为类型的一部分,类似于构造函数参数成为新实例的一部分。
然后,每当您声明StopAlarmTask
,您将提供一个类型,例如String
,以填充类型参数T
然后,您可以在类主体中引用该类型参数。 例如,您可以定义采用T
或返回T
,或使用T
参数化成员变量(如fSchedFuture
。 例如,如果您将StopAlarmTask
的声明参数化为StopAlarmTask
,那么String
将被捕获为T
并且无论您在该StopAlarmTask
使用T
,它都将充当String
。
但是,在您列出的代码中, StopAlarmTask
没有类型参数,无法使用任何类型进行参数化。 在类体中没有捕获的类型称为T
另一方面, >
表示“我不知道它将是哪种类型;我甚至不知道它将是某人用来参数化StopAlarmTask
的类型。”
你可以参数化StopAlarmTask
,在这种情况下你可以有两个变量:
private ScheduledFuture fSchedFuture1; private ScheduledFuture> fSchedFuture2;
第一个声明表明ScheduledFuture
的类型参数与封闭的StopAlarmTask
的类型参数相同。 例如, StopAlarmTask
会使fSchedFuture1进入ScheduledFuture
。 第二个声明说我们不知道ScheduledFuture
的类型参数是什么,即使我们知道封闭的StopAlarmTask
的类型参数。
假设this.executorService
是ScheduledExecutorService
的子类型(自Java 1.5起可用),则scheduleWithFixedDelay()
的返回类型为ScheduledFuture>
。 您无法将ScheduledFuture>
的返回类型更改为ScheduledFuture
, ScheduledFuture
或其他任何内容。 但是,您可以将其更改为ScheduledFuture
因为>
是一个通配符generics类型参数,它近似于原始类型以实现向后兼容。
请参阅什么是原始类型,为什么我们不应该使用它? 有关原始类型和generics的良好讨论。
小丑?
可以举行任何类型。 如果要对所有方法/成员使用相同的类型,则可以使整个类具有通用性。 通过编写StopAlarmTask
您可以在整个类中定义类型T
private final class StopAlarmTask implements Runnable { StopAlarmTask(ScheduledFuture aSchedFuture) { fSchedFuture = aSchedFuture; } public void run() { /* */ } private ScheduledFuture fSchedFuture; }
它可以采用任何参数,如Object,String,Integer ….等等
现在,当您计划使用generics时,您必须在天使括号内提供类型。
编辑:
>
严格适用于Collections。
用作普通class级的类型或模板
StopAlarmTask
不是generics类型。
在下面的示例中,您不会认为Foo
是generics类型。
class Foo { Foo(int i) { } doStuff(List numbers) { } }
StopAlarmTask
的构造 StopAlarmTask
使用generics参数这一事实不会使类通用,只是doStuff()
使Foo
成为generics。
使用>
以通用方式 “引用”generics类型的声明,即没有特异性。 在StopAlarmTask
它恰好是构造函数参数。 它是generics类型的“使用”而不是generics类型的声明,因为它“仅仅”是参数声明。
换句话说,简短的回答是方法中的参数
StopAlarmTask(ScheduledFuture> aSchedFuture) { ... }
适用于作为所有 ScheduledFuture
的 ScheduledFuture
实例的所有对象 。
以下是generics的进一步背景。
使用
或
或其他任何方式声明generics类型ScheduledFuture
。 具体来说, >
不会在ScheduledFuture<>
的声明中使用,因为约定是使用单个大写字母。
请注意,以下测试代码,如果提供给编译器,将显示第一个类编译但第二个类不编译,所以说有一个使用字母的约定实际上是轻描淡写。
class TGeneric1 { List list = new ArrayList (); TGeneric1(E value) { this.list.add(value); } E getHead() { return this.list.get(0); } } class TGeneric2> { List> list = new ArrayList>(); TGeneric2(? value) { this.list.add(value); } ? getHead() { return this.list.get(0); } }
在以下测试代码中说明,没有单个字母约束,因此以下也是正确的。
class TGeneric1 { List list = new ArrayList (); TGeneric1(EE value) { this.list.add(value); } EE getHead() { return this.list.get(0); } }