泛型
泛型的来源,首先我们知道类是存在聚合的,就是这个类有其他类的对象;那么问题来了,我今天用你,明天用别人;怎么办呢?
public class Automobile {
}
public class Holder1 {
private Automobile a;
public Holder1(Automobile a) //完全不能改变的时候
{
this.a=a;
}
Automobile get()
{
return a;
}
private Object b;
public Holder1(Object b)
{
this.b=b;
}
public void setB(Object b)
{
this.b = b;
}
public Object
getB() {
return b;
}
}
然后泛型自然就出来;
public class Holder2<T> {
private T a;
public Holder2(T a) {
this.a = a;
}
public T
getA() {
return a;
}
public void setA(T a) {
this.a = a;
}
}
元组类库
就是通过泛型聚合多个类对象;使得一个对象可以携带多个对象,而且还是可以随便更改的对象;
泛型方法
不靠泛型类,方法泛型就行,就像下面static方法如果使用泛型必须成为泛型方法,简单的讲,因为static方法和类一起加载,那时就可以直接调用static方法了,而你的tpye是啥都不知道;而构造函数虽然也是隐藏的static,但我们就是通过人家获得的tpye的,soso。。
public class GenericMethods {
public <T>
void f(T x)
{
System.out.println(x.getClass().getName());
}
public static void main(String [] arg)
{
GenericMethods genericMethods =
new GenericMethods();
genericMethods.f(
"");
genericMethods.f(
1);
genericMethods.f(
new HelloA());
}
}
吐槽
编程思想这本书真的是,有太多和java思想无关的内容,而只是经验之谈,还有一些事设计模式,说的太杂;
泛型擦除
public class Foo<T> {
T a;
List<T> create (T t,
int n)
{
List<T> result =
new ArrayList<T>();
for (
int i =
0;i< n ;i++) {
result.add(t);
}
return result;
}
public String
toString()
{
return a.getClass().getName();
}
public static void main(String []arg)
{
Foo<Holder1> holder1Foo=
new Foo<>();
Foo<String> foo =
new Foo<>();
List<String> list= foo.create(
"hello",
4);
System.out.println(list);
System.out.println(holder1Foo.getClass().getName());
System.out.println(holder1Foo.toString());
}
}
协变
子类可以赋值给父类,就称为协变;数组也可以协变,但是这货会存在陷阱一样的错误
class Fruit {}
class Apple extends Fruit {}
class Jonathan extends Apple {}
class Orange extends Fruit {}
public class CovariantArrays {
public static void main(String[] args) {
Fruit[] fruit =
new Apple[
10];
fruit[
0] =
new Apple();
fruit[
1] =
new Jonathan();
try {
fruit[
0] =
new Fruit();
}
catch(Exception e) { System.out.println(e); }
try {
fruit[
0] =
new Orange();
}
catch(Exception e) { System.out.println(e); }
}
}
然后就是泛型了,它不支持协变,父类和子类不能直接赋值;
通配符
public static void printList(List<?> list) {
for (
int i =
0; i < list.size(); i++) {
System.out.println(list.get(i));
}
list.add(
1);
list.add(
"123");
}
原因在于:?就是表示类型完全无知,? extends E表示是E的某个子类型,但不知道具体子类型,如果允许写入,Java就无法确保类型安全性。假设我们允许写入,如果我们传入的参数是List,此时进行add操作,可以添加任何类型元素,就无法保证List的类型安全了。
超类型
public static void printList(List<?
super String> list) {
for (
int i =
0; i < list.size(); i++) {
System.out.println(list.get(i));
}
list.add(
"123");
list.add(
"456");
}
这个很好理解,list的参数类型是String的上界,必然可以添加String类型的元素。
转载请注明原文地址: https://ju.6miu.com/read-15016.html