java 泛型接口_java泛型接口 - CSDN
精华内容
参与话题
  • Java泛型接口的使用

    千次阅读 2019-01-09 15:55:50
    public class Test5 { public static void main(String[] args) { Message<String> mes=new Message<...这是泛型接口中的print()方法,此时传入的String类型"); ...
    public class Test5 {
        public static void main(String[] args) {
    
            Message<String> mes=new Message<String>();
            System.out.println("这是泛型接口中的print()方法,此时传入的String类型");
            mes.print("SBABprint");
    
            Message<Integer> inte=new Message<>();
            System.out.println("这是泛型接口中的print()方法,此时传入的Integer类型");
            inte.print(123);
    
            Message2 message2=new Message2();
            message2.print("Message2实例化对象");
            message2.print2();
        }
    }
    
    //定义一个泛型接口
    interface IMessage<T>{
        public void print(T t);
    }
    //子类实现接口的时候使用泛型接口,在实例化的时候指定类型
    class Message<T> implements IMessage<T>{
        @Override
        public void print(T t) {
            System.out.println(t);
        }
    }
    
    //子类实现接口的时候给出指定类型
    class Message2 implements IMessage<String>{
        @Override
        public void print(String s) {
            System.out.println(s);
        }
        public void print2(){
            System.out.println("Message2 的 print2()方法");
        }
    }
    
    展开全文
  • 范例1:接口设置泛型,子类也设置泛型interface MyMessage&lt;T&gt; { public void print(T t); } class Message&lt;T&gt; implements MyMessage&lt;T&gt; { @Override public void ...

    范例1:接口设置泛型,子类也设置泛型

    interface MyMessage<T> {
    	public void print(T t);
    }
    
    class Message<T> implements MyMessage<T> {
    	@Override
    	public void print(T t) {
    		System.out.println(t);
    	}
    }
    
    public class Demo {
    	public static void main(String[] args) {
    		MyMessage<String> msg = new Message<>();
    		msg.print("Hello!");
    	}
    
    }

    ================分割线================

    范例2:子类不设置泛型吗,为父类接口定义明确泛型标记

    interface MyMessage<T> {
    	public void print(T t);
    }
    
    class Message implements MyMessage<String> {
    	@Override
    	public void print(String t) {
    		System.out.println(t);
    	}
    }
    
    public class Demo {
    	public static void main(String[] args) {
    		MyMessage<String> msg = new Message();
    		msg.print("World!");
    	}
    
    }

    展开全文
  • 泛型允许我们使用类型参数Type parameter,它用一个自定义的标识符(T、V、E)来代表一个类型,用括住,放在类名后面。然后在类定义中所有使用该类型的地方都用这个标识符来代替,因为在定义这个类的时候还不知道这个...


    泛型按照使用方法分为三种情况:

    1. 泛型类
    2. 泛型接口
    3. 泛型方法

    泛型类

    • 泛型允许我们使用类型参数Type parameter,它用一个自定义的标识符(T、V、E)来代表一个类型,用< >括住,放在类名后面。然后在类定义中所有使用该类型的地方都用这个标识符来代替,因为在定义这个类的时候还不知道这个具体类型到底是哪个类型。
    • 可使用类型参数Type parameter的地方:声明变量、形参、返回值、强制类型转换。注意不可以用于构造器。
    • 使用泛型类时(区别于定义泛型类时),< >里面的类型必须被具体类型或定义泛型类时的类型参数所确定。如果是被定义泛型类时的类型参数确定的这种情况,则是把确定类型的任务交给了定义泛型类,这种情况常出现在泛型类的继承、或内部类。
    • 泛型与多态不冲突。当使用泛型类class store<phone>时,你既可以使用phone,也可以使用vivoPhone

    泛型类的继承

    class two<A,B> {//定义泛型类
    }
    class three<C> extends two<A, B> {//报错can't resolve symbol 'A',can't resolve symbol 'B'
    }
    
    class two<A,B> {
    }
    class three<A,B,C> extends two<A, B> {
    }
    

    在第一段代码中,类three的声明会报错,而第二段不会。这是因为,class three<A,B,C>属于声明泛型类,而extends two<A, B>属于使用泛型类。使用泛型类的时候类型参数必须被确定,这里extends two<A, B>中的A,B被泛型类class three<A,B,C>的声明里的A,B所确定。
    虽然extends two<A, B>中的A,B不是具体类型却还是类型参数,但有了声明泛型类class three<A,B,C>的保证,A,B最终能被具体类型所确定。

    泛型与内部类

    此例实现了一个简单的栈,内部原理是链式存储。

    // A stack implemented with an internal linked structure.
    
    public class LinkedStack<T> {//声明泛型类
        private static class Node<U> {//声明泛型类
            U item;
            Node<U> next;
            Node() { item = null; next = null; }
            Node(U item, Node<U> next) {
                this.item = item;
                this.next = next;
            }
            boolean end() { return item == null && next == null; }
        }
        private Node<T> top = new Node<T>(); //使用泛型类,但这里被定义泛型类的类型参数确定
        public void push(T item) {
            top = new Node<T>(item, top);
        }   
        public T pop() {
            T result = top.item;
            if(!top.end())
                top = top.next;
            return result;
        }
        public static void main(String[] args) {
            LinkedStack<String> lss = new LinkedStack<String>();
            for(String s : "Phasers on stun!".split(" "))
                lss.push(s);
            String s;
            while((s = lss.pop()) != null)
                System.out.println(s);
        }
    } /* Output:
    stun!
    on
    Phasers
    *///:~
    

    类LinkedStack中有个内部类Node,它们都是泛型类。在定义泛型类Node时,类型参数没有被确定,当然也不需要被确定。在使用泛型类private Node<T> top = new Node<T>()时,Node的类型参数被定义泛型类LinkedStack的T所确定,因为这句private Node<T> top = new Node<T>()处于LinkedStack的类定义中,所以这样用也合理。

    泛型接口

    • 各方面和泛型类都是类似的。自定义的标识符(T、V、E)来代表一个类型,用< >括住,放在接口名后面。
    • 使用泛型接口时,< >里面的类型必须被具体类型、定义泛型类或泛型接口时的类型参数所确定。不过一般泛型接口多被具体类型确定。

    泛型接口的实现

    interface two<A>{
    
    }
    class three<A,B> implements two<A>{
    
    }
    interface four<A,B> extends two<A>{
        
    }
    

    上例说明了使用泛型接口时,可以被定义泛型类或泛型接口时的类型参数所确定。

    interface two<A>{
        A f(A a);
    }
    class impl implements two<Object>{
        public Object f(Object a){
            return new Object();
        }
    }
    

    当使用泛型接口时,确定好的具体类型要覆盖掉原来的所有使用类型参数的地方。比如类impl中的f方法中,所有使用A的地方都要用Object替换掉。

    泛型方法

    • 自定义的标识符(T、V、E)来代表一个类型,用< >括住,放在方法返回值前面。可以被用到形参声明、方法返回值、方法定义中的变量声明和类型转换。
    • 泛型方法使得该泛型方法的类型参数独立于类而产生变化。泛型方法和泛型类没有关系。
    • 泛型方法的类型参数,一般情况下都是被推断inference出来。更具体地讲,只能被形参或返回值推断出来,当形参和返回值用了同一个类型参数时,二者推断出来的类型必须一样、或者符合多态。
    • 形参的类型参数通过实参确定;返回值的类型参数通过方法返回值赋值的对象确定。这也就是类型参数推断
    • 当形参的类型参数和返回值的类型参数是同一个时,优先使用形参的推断。因为返回值的类型参数的推断是一种拖延行为。
    • 类的成员方法可以使用定义泛型类的类型参数(注意,这种方法不是泛型方法,只不过使用了类型参数而已);而类的静态方法不可以使用泛型类的类型参数,这是因为只有当创建泛型类对象时类型参数才会被具体类型确定,也就是说,泛型类的类型参数是与对象相关的。那么,很自然地,作为一个static方法肯定不可以使用泛型类的类型参数。static方法想用到泛型只能将其定义为泛型方法。

    形参的类型参数通过实参确定

    class GenericMethods {
        public <T> void f(T x) {
            System.out.println(x.getClass().getName());
        }
        public void testInt(){
            f(1);
        }
    }
    
    public class testP {
        public static void main(String[] args) {
            GenericMethods gm = new GenericMethods();
            gm.f("");
            gm.f(1);
            gm.f(1.0);
            gm.f(1.0F);
            gm.f('c');
            gm.f(gm);
            gm.testInt();
        }
    }
    

    f方法是一个泛型方法,返回值是void,形参是< >里的T。调用泛型方法,既可以通过对象来调用,例如gm.f("");,此时T被推断为String类型;也可以在除该泛型方法外,且类定义中调用,例如testInt()方法中,此时T被推断为int类型。
    泛型方法和自动打包让f方法看起来像是被无限重载了一样。

    泛型方法被多个形参推断

    public class Test {  
        public static void main(String[] args) {  
    
            /**依靠类型参数推断*/  
            int i = Test.add(1, 2); //这两个参数都是Integer,所以T为Integer类型  
            Number f = Test.add(1, 1.2); //这两个参数一个是Integer,以风格是Float,所以取同一父类的最小级,为Number  
            Object o = Test.add(1, "asd"); //这两个参数一个是Integer,以风格是Float,所以取同一父类的最小级,为Object  
    
            /**显式的类型说明*/  
            int a = Test.<Integer>add(1, 2); //指定了Integer,所以只能为Integer类型或者其子类  
            int b = Test.<Integer>add(1, 2.2); //编译错误,指定了Integer,不能为Float  
            Number c = Test.<Number>add(1, 2.2); //指定为Number,所以可以为Integer和Float  
        }  
    
        //这是一个简单的泛型方法  
        public static <T> T add(T x,T y){  
            return y;  
        }  
    }
    

    add方法的两个形参都使用到了类型参数T,即使用了同一个类型参数。那么在推断的时候会依靠两个实参的共同最小父类来推断(就好像数学里的最小公倍数)。

    返回值的类型参数通过方法返回值赋值的对象确定

    class GenericMethods {
        public <T> T f2(Object x) {
            System.out.println(x.getClass().getName());
            return (T)x;
        }
    }
    
    public class testP {
        public static void main(String[] args) {
            GenericMethods gm = new GenericMethods();
            int o1 = gm.f2(2);
            String o2 = gm.f2(2);//能通过编译,但运行时报错
            gm.f2(1.2);//
        }
    }
    

    f2方法是一个泛型方法,返回值是< >里的T,形参是Object x。

    • 执行int o1 = gm.f2(2)后,由于f2方法返回值赋值给了一个int变量,那么这里T就被推断为了int,并且在f2方法的运行过程中,所有使用T的地方都会替换为int,所以return (T)x;实际是执行的return (int)x;。所以,整个运行过程是,2被向上转型为Object,然后强行cast为了int,最后被返回出来。
    • 执行String o2 = gm.f2(2)后,由于这里T就被推断为了String,一个实际为2的Object对象在向上转型为String类型时,会受到RTTI的检查,被发现无法转型后便报错。
    • 执行gm.f2(1.2)后,由于返回值没有赋值给对象,所以T没有被推断出来,也不需要被推断出来。因为没有进行赋值,返回值并不关心。

    形参和返回值用了同一个类型参数

    class A{}
    class B extends A{}
    
    class GenericMethods {
        public <T> T f1(T x) {
            System.out.println(x.getClass().getName());
            return x;
        }
    }
    
    public class testP {
        public static void main(String[] args) {
            GenericMethods gm = new GenericMethods();
            int i = gm.f1(1);
            //String s = gm.f1(1);
            A a = gm.f1(new B());
            //B b = gm.f1(new A());
        }
    }
    

    f1方法是一个泛型方法,返回值是< >里的T,形参也是< >里的T。这种情况只使用形参的类型推断,因为靠返回值推断是一种推延行为。

    • 执行int i = gm.f1(1)时,形参处的T被推断为int,所以没有问题。
    • 执行String s = gm.f1(1)时,形参处的T被推断为int,然后返回值int赋值给一个String类型,所以这里编译报错。
    • 执行A a = gm.f1(new B())时,形参处的T被推断为B。然后返回值B对象赋值给一个A类型,这里向上转型。
    • 执行B b = gm.f1(new A())时,形参处的T被推断为A。然后返回值A对象赋值给一个B类型,这里向下转型,不可以,编译报错。
    • 这里如果是B b = (B) gm.f1(new A())则能够编译通过。这里把工作交给了强制类型转换,编译器便不会报错了,但运行报错。

    泛型方法定义中的类型推断

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class New {
        public static <K,V> Map map() {
            return new HashMap<K,V>();//泛型方法定义中使用类型参数
        }
        public static <T> List list() {
            return new ArrayList<T>();
        }
        public static void main(String[] args) {
            Map<String,List<String>> sls = New.map();
            List<String> ls = New.list();
        }
    }
    

    注意这种情况一般都是发生在return语句里。通过泛型方法的赋值,推断出了泛型方法定义中的类型参数的具体类型。

    静态方法不可以使用泛型类定义的类型参数

    class two<A>{
        public void f(A a){//只是一个使用了类型参数的成员方法
            System.out.println(a);
        }
    
    //    public static void f1(A a){//静态方法不可以使用泛型类定义的类型参数
    //        System.out.println(a);
    //    }
    
        public static <A> void staticF(A a){//泛型方法,静态方法
            System.out.println(a);
        }
    
        public <A> void memberF(A a){//泛型方法,成员方法
            System.out.println(a);
        }
    }
    

    注意staticF方法里的A和two<A>里的A没有任何关系。同样,memberF方法里的A和two<A>里的A没有任何关系。因为这二者都是泛型方法。
    two<A>里的A是与对象相关的,只有创建对象时才能确定。f1是静态方法,自然不可能与对象相关的东西有关系。

    泛型方法返回值赋值给形参

    这种情况区别于泛型方法返回值赋值给变量。

    import java.util.HashMap;
    import java.util.Map;
    
    class LimitsOfInference {
        static void f(Map<String,Integer> petPeople) {
    
        }
        public static void main(String[] args) {
             f(New.map()); //报一个警告
        }
    }
    
    public class New {
        public static <K,V> Map map() {
            return new HashMap<K,V>();
        }
    }
    

    警告内容为:在这里插入图片描述
    说明泛型方法中的类型参数并没有被推断出来,所以这里泛型方法返回值只知道是个Map

    而为了这里不报警告,则需要使用显示的类型说明,在调用泛型方法时,在点操作符和方法名之间插入尖括号,然后把具体类型放在里面。这种语法很少见,在这样的非赋值语句中,才需要用到,一般用类型参数推断就可以解决。

    import java.util.HashMap;
    import java.util.Map;
    
    class LimitsOfInference {
        static void f(Map<String,Integer> petPeople) {
    
        }
        public static void main(String[] args) {
             f(New.<String,Integer>map()); //不报任何警告
        }
    }
    public class New {
        public static <K,V> Map map() {
            return new HashMap<K,V>();
        }
    }
    

    可变参数和泛型方法

    import java.util.*;
    
    public class GenericVarargs {
        public static <T> List<T> makeList(T... args) {
            List<T> result = new ArrayList<T>();
            for(T item : args)
                result.add(item);
            return result;
        }
        public static void main(String[] args) {
            List<String> ls = makeList("A");
            System.out.println(ls);
            ls = makeList("A", "B", "C");
            System.out.println(ls);
            ls = makeList("ABCDEFFHIJKLMNOPQRSTUVWXYZ".split(""));
            System.out.println(ls);
        }
    } /* Output:
    [A]
    [A, B, C]
    [, A, B, C, D, E, F, F, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z]
    *///:~
    

    makeList方法的功能类似于java.util.Arrays.asList()的功能。

    泛型类和泛型方法

    此例中泛型类和泛型方法同时存在。有一个泛型接口Generator用来产生某种对象。CountedObject类必须有默认构造器因为newInstance。

    interface Generator<T> {
        T next();
    }
    
    class CountedObject {
        private static long counter = 0;
        private final long id = counter++;// 用于记录创建对象的次数
        public long getId() {
            return id;
        }
        public String toString() {
            return "CountedObject" + id;
        }
    }
    
    public class BasicGenerator<T> implements Generator<T> {
        private Class<T> type;
        public BasicGenerator(Class<T> type) {
            this.type = type;
        }
        
        @Override
        public T next() {
            try {
                return type.newInstance();
            } catch (InstantiationException | IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
        
        public static <T> Generator<T> create(Class<T> type) {//静态泛型方法
            return new BasicGenerator<T>(type);
        }
      
        public static void main(String[] args) {
            Generator<CountedObject> gen = BasicGenerator.create(CountedObject.class);
            for (int i = 0; i < 5; i++) {
                System.out.println(gen.next());
            }
        }
    }
    
    • create方法是静态的泛型方法,而泛型类 BasicGenerator 的类型参数是与对象相关的,所以 create方法里的 T 不是泛型类的 T。或者说,在create方法里,create方法的<T>暂时隐藏了BasicGenerator<T><T>,这使得泛型方法的类型参数独立于对象。
    • 此例体现了泛型方法的好处,由于泛型方法的类型参数推断,所以这里允许执行BasicGenerator.create(CountedObject.class),而不是去执行麻烦的new BasicGenerator<CountedObject>(CountedObject.class)。简单的说,让你少写了尖括号。
    • 注意一下create方法的return语句和返回值,可以看出Generator<CountedObject>BasicGenerator<CountedObject>的父类。注意这种与泛型有关的多态。

    泛型类中的成员泛型方法和静态泛型方法

    对上例进行修改,使其同时拥有成员的泛型方法和静态的泛型方法,且这两种泛型方法使用的类型参数和泛型类的类型参数是同一个(都用的T)。staticCreatememberCreate的返回值都进行了修改,使其返回子类BasicGenerator而不是父接口Generator,这是为了对象方便调用新增加的成员方法。

    //前面省略
    public class BasicGenerator<T> implements Generator<T> {
        private Class<T> type;
        public BasicGenerator(Class<T> type) {
            this.type = type;
        }
    
        @Override
        public T next() {
            try {
                return type.newInstance();
            } catch (InstantiationException | IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
    
        public static <T> BasicGenerator<T> staticCreate(Class<T> type) {//静态的泛型方法
            return new BasicGenerator<T>(type);
        }
    
        public <T> BasicGenerator<T> memberCreate(Class<T> type) {//成员的泛型方法
            return new BasicGenerator<T>(type);
        }
    
        public <T> void test (T t) {//成员的泛型方法
            System.out.println(t.getClass().getName());
        }
    
        public static void main(String[] args) {
            BasicGenerator<CountedObject> gen = BasicGenerator.staticCreate(CountedObject.class);
            for (int i = 0; i < 5; i++) {
                System.out.println(gen.next());
            }
            gen.test("");//这里独立于类,泛型方法test推断出了自己的类型参数T为String,而不是gen对象确定的CountedObject
            gen.test(1);
            BasicGenerator<String> gen1 = gen.memberCreate(String.class);
            System.out.println(gen1.type.getName());
        }
    }/*output:
    CountedObject0
    CountedObject1
    CountedObject2
    CountedObject3
    CountedObject4
    java.lang.String
    java.lang.Integer
    java.lang.String
    */
    

    从运行结果可以看出:泛型方法不管是静态的还是成员的,就算和泛型类使用了同一个类型参数T,在泛型方法中也会暂时隐藏泛型类的类型参数,而使用自己的类型参数,并且把确定具体类型的任务交给了类型参数推断。这样,就做到了泛型方法能够独立于泛型类的类型参数而产生变化

    匿名内部类和泛型

    本例使用了匿名内部类来继承并实现泛型接口。

    interface Generator<T> {//定义泛型接口
        T next();
    }
    
    class Customer {
        private static long counter = 1;
        private final long id = counter++;
        private Customer() {}
        public String toString() { return "Customer " + id; }
        // A method to produce Generator objects:
        public static Generator<Customer> generator() {
            return new Generator<Customer>() {//使用泛型接口
                public Customer next() { return new Customer(); }
            };
        }
    } 
    

    return new Generator<Customer>()这里属于使用泛型接口,既然是使用,那么必须把类型参数确定下来,并且把使用了类型参数的地方进行替换,替换为Customer。继承并实现泛型类的匿名内部类同理。

    个人理解总结

    • 泛型的类型参数看起来就像是让代码变成了一套模板,当给定具体类型时,模板里的类型参数就会被替换以生效。
    • 泛型这种类似“模板”的灵活性,在使用泛型时(生成泛型类对象)得以体现,但在使用泛型后(在泛型类对象上调用方法)失去。
    展开全文
  • java泛型接口

    千次阅读 2018-06-17 12:22:50
    java泛型接口 泛型接口 格式: 访问权限 interface 接口名&amp;lt;泛型标示&amp;gt;{} interface Info&amp;lt;T&amp;gt;{ public T getValue(); } class InfoImpl implements Info { ...

    java泛型接口

    泛型接口
    格式:
    访问权限 interface 接口名<泛型标示>{}

    interface Info<T>{
        public T getValue();
    }
    
    class InfoImpl implements Info {
        public String getVar() {
            return null;
        }
    }

    子类定义泛型的类型

    interface Info<T>{
        public T getValue();
    }
    
    class InfoImpl<T> implements Info<T> {
        private T var;
        public InfoImpl(T var) {
            this.setVar(var);
        }
        public void setVar(T var) {
            this.var = var;
        }
        public T getVar() {
            return this.var;
        }
    }
    public class GenericsDemo24 {
        public static void main(String args[]) {
            Info<String> i = null;
            i = new InfoImpl<String>("123");
            System.out.println("hello: " + i.getVar());
        }
    }

    另一种实现方式, 子类直接使用具体的类型

    interface Info<T>{        // 在接口上定义泛型
        public T getVar() ; // 定义抽象方法,抽象方法的返回值就是泛型类型
    }
    class InfoImpl implements Info<String>{   // 定义泛型接口的子类
        private String var ;                // 定义属性
        public InfoImpl(String var){        // 通过构造方法设置属性内容
            this.setVar(var) ;
        }
        public void setVar(String var){
            this.var = var ;
        }
        public String getVar(){
            return this.var ;
        }
    };
    public class GenericsDemo25{
        public static void main(String arsg[]){
            Info i = null;      // 声明接口对象
            i = new InfoImpl("Hello") ;   // 通过子类实例化对象
            System.out.println("内容:" + i.getVar()) ;
        }
    };

    定义泛型方法

    格式:
    访问权限 <泛型标识> 泛型标识 方法名称(泛型标识 参数名称)

    class Demo{
        public <T> T fun(T t){            // 可以接收任意类型的数据
            return t ;                  // 直接把参数返回
        }
    };
    public class GenericsDemo26{
        public static void main(String args[]){
            Demo d = new Demo() ;   // 实例化Demo对象
            String str = d.fun("Hello") ; //  传递字符串
            int i = d.fun(30) ;     // 传递数字,自动装箱
            System.out.println(str) ;   // 输出内容
            System.out.println(i) ;     // 输出内容
        }
    };

    泛型使用中类型推导方式

    1. 通过泛型方法返回泛型类的实例
    class Info<T extends Number>{ // 指定泛型的类别,只能是数字类型
        private T var ;     // 此类型由外部决定
        public T getVar(){
            return this.var ;
        }
        public void setVar(T var){
            this.var = var ;
        }
        public String toString(){ // 覆写Object类中的toString()方法
            return this.var.toString();
        }
    }
    public class GenericsDemo27{
        public static void main(String args[]){
            Info<Integer> i = fun(30);
            System.out.println(i.getVar());
        }
        public static <T extends Number> Info<T> fun(T param){
            Info<T> temp = new Info<T>() ;      // 根据传入的数据类型实例化Info
            temp.setVar(param) ;        // 将传递的内容设置到Info对象的var属性之中
            return temp ;   // 返回实例化对象
        }
    }
    1. 使用泛型统一传入参数的类型
    class Info<T>{
        private T var ;     // 此类型由外部决定
        public T getVar(){
            return this.var ;
        }
        public void setVar(T var){
            this.var = var ;
        }
        public String toString(){ // 覆写Object类中的toString()方法
            return this.var.toString();
        }
    }
    public class GenericsDemo28{
        public static void main(String args[]){
            Info<String> i1 = new Info<String>() ;
            Info<String> i2 = new Info<String>() ;
            i1.setVar("HELLO") ;        // 设置内容
            i2.setVar("WORLD") ;      // 设置内容
            add(i1,i2) ;
        }
        public static <T> void add(Info<T> i1,Info<T> i2){
            System.out.println(i1.getVar() + " " + i2.getVar()) ;
        }
    }
    1. 如果add方法中两个泛型的类型不统一,则编译会出错。
    class Info<T>{
        private T var ;     // 此类型由外部决定
        public T getVar(){
            return this.var ;
        }
        public void setVar(T var){
            this.var = var ;
        }
        public String toString(){       // 覆写Object类中的toString()方法
            return this.var.toString() ;
        }
    }
    public class GenericsDemo29{
        public static void main(String args[]){
            Info<Integer> i1 = new Info<Integer>() ;
            Info<String> i2 = new Info<String>() ;
            i1.setVar(30) ;     // 设置内容
            i2.setVar("XiaoHua") ;      // 设置内容
            add(i1,i2) ;
        }
        public static <T> void add(Info<T> i1,Info<T> i2){
            System.out.println(i1.getVar() + " " + i2.getVar()) ;
        }
    }
    展开全文
  • Java反射操作泛型接口

    千次阅读 2018-07-13 18:12:03
    通过反射获取到抽象类或者接口中泛型信息的操作也是很常见的...getGenericInterfaces()获取到泛型接口的Type数组。 getActualTypeArguments()获取到泛型接口的实际类型。 1. 定义一个泛型的接口: package com...
  • Java 泛型方法/接口泛型限定

    万次阅读 多人点赞 2020-08-26 20:43:32
    文章目录
  • Java泛型接口的定义

    千次阅读 2019-06-22 19:41:23
    接口也可以定义泛型,语法如下: [public] interface接口名<T> 二代码 public class GeneralInterface { public static void main( String[] args ) { System.out.println(new TestIBase().getA()); } ...
  • 含有泛型接口 定义格式: 修饰符 interface接口名<代表泛型的变量> { } 例如, //迭代器接口 public interface Iterator<E>{ public abstract E next(); } //Scanner实现了Iterator接口,并指定...
  • 痛点: 使用Mybatis框架的时候,想封装一个底层JDBC控制器,用于提供和Mybatis交互的增删改查接口(公用的接口),但由于公用的查询方法可能是用户自定义的任意一个和表对应的java bean类型,所以要考虑怎么样给调用...
  • 前言:在向上抽取功能时可能会有需要获取到实现接口的实际泛型参数类型这样的需求,分享一下自己实现的方法。 一、Java 代码 直接上代码,代码上有注释,对API做了相应的解释。 public BasicAction(){ try { ...
  • 泛型示例三:public class TPractice&lt;T extends Calendar &amp; SolarTerms &amp; Festival&gt; { // 限制 T类型为继承Calendar 类,并实现SolarTerms、Festival 接口的类类型 private T obj; ...
  • java泛型 方法返回值带有泛型 <T>

    万次阅读 2019-05-16 15:59:01
    方法返回值前的<T>的左右是告诉编译器,当前的方法的值传入类型可以和类初始化的泛型类不同,也就是该方法的泛型类可以自定义,不需要跟类初始化的泛型类相同 ...
  • * 在接口中定义泛型 * */ public interface Ieat { public void eat(T t); } class MyIeat implements Ieat{ public MyIeat(){ } @Override public void eat(String t) { System.out.println(t);
  • Java泛型

    万次阅读 2015-11-01 11:23:56
    就像 平时我们预先定义的接口一样 (接口 只不过是推迟方法的实现 ) 然而这个Java泛型的就是 推迟告知java 虚拟机的所使用对象的类型。 通过这个这种方式到达一种通用编程的效果。 1,泛型 包裹 (泛型类,泛型...
  • Java中引入泛型的好处

    千次阅读 2016-12-13 10:57:33
    这种类型参数可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。   在没有泛型的情况下,通过对类型Object的引用来实现参数的转换,这种转换是需要显式地强制类型转换,对于强制类型转换错误...
  • Java Type接口 & 运行时获取泛型类型

    万次阅读 2018-05-15 09:18:21
    一、Type接口 Type是所有类型的父接口,他有4个子接口和一个实现类。
  • Java获取类或接口上的泛型类型T方法

    千次阅读 2019-12-27 10:48:09
    前言 实际开发中,泛型使用到处可见。有时候定义接口时,经常使用泛型,而不是指定具体对象,使用泛型的好处很多,特别是代码复用方面。要获取类或接口上的泛型类型Class<...1.定义泛型接口 public interface Res...
  • java泛型-implements和extends

    千次阅读 2018-08-26 12:57:42
    JavaSE当中之前的理解是:implements是实现接口,extends是继承类,但是在泛型中只能使用extends,不过只能使用extends并不意味着只能继承类,泛型使用extends后边既可以接父类又可以跟接口,最终实现的效果跟继承类...
  • 1.学习之前我们先来了解一些泛型的术语 &amp;amp;amp;amp;amp;lt;&amp;amp;amp;amp;amp;gt;: 念做typeof List&amp;amp;amp;amp;amp;lt;E&amp;amp;amp;amp;amp;gt;: E称为类型参数变量 ArrayList&...
  • Java 运行时如何获取泛型参数的类型

    万次阅读 2017-02-06 09:24:46
    Java 中对于下面最简单的泛型类 class A { public void foo() { //如何在此处获得运行时 T 的具体类型呢? } } 设想我们使用时 new A().foo(); 是否能在 foo() 方法中获得当前的类型是 String ...
1 2 3 4 5 ... 20
收藏数 110,785
精华内容 44,314
关键字:

java 泛型接口