Java Generic Common Interview Questions of Interview Required Questions

  • 2021-09-12 01:08:50
  • OfStack

Directory 1, Basic Concepts of Generics 1.1 Why Do You Need Generics 1.2 What Are Generics 2, Generic Definitions and Use 2.1 Generic Classes\ Generic Interfaces 2.2 Generic Methods 2.3 Inheritance of Generic Classes 2.4 Type Wildcards? And its upper and lower limits

1. Basic concepts of generics

1.1 Why do you need generics


 List list = new ArrayList();// The default type is Object
        list.add("A123");
        list.add("B234");
        list.add("C345");
        System.out.println(list);

        for(int i=0;i<list.size();i++){
            // To set the list Assign the elements in the String Variable, need to be type converted, otherwise it will be reported Incompatible types Error, display list.get(i) Returns the Object
            String str =  (String) list.get(i);
            System.out.println(str);
        }
​   
        list.add(123);// Because the type is Object , we can put Integer Elements of type or other data types are also added list In 
        System.out.println(list.get(3));
​
        for(int i=0;i<list.size();i++){
            //String str =  (String) list.get(i);// But an error will be reported here java.lang.ClassCastException , we can't just put Integer Data of type is converted to String
            System.out.println(list.get(i).getClass());
        }

As shown in the code, when we define an List, and the default type of list is the base class Object of all objects, we need to go through a type conversion before we can operate on the actual type of the object. Since the type in List is Object, it is also allowed to add String data first, then Integer or other types of data. Because List is Object data at compile time, but it is its own type at run time, it will be thrown when we treat the data in List as String java.lang.ClassCastException .

Is there any way that the collection can remember the types of elements in the collection, so that as long as there are no problems at compile time, they will not appear at run time java.lang.ClassCastException What about anomalies? The answer is to use generics.

1.2 What are generics

The Java generic design principle is that as long as there are no warnings at compile time, there will be no ClassCastException exceptions at run time.

Generics, or "parameterized types," defer the work of type definition until the creation of an object or the invocation of a method < Data type > Pass it as if it were parameter 1.

What are generics? Why use generics?

Generics, that is, "parameterized types". 1 When it comes to parameters, the most familiar thing is to define a method with tangible parameters, and then pass arguments when the method is called. So what about parameterized types?

As the name implies, it is to parameterize the type from the original concrete type, similar to the variable parameters in the method, and then the type is also defined as a parameter (you can call it a type parameter).

Then pass in the concrete type (type argument) when using/calling.

The essence of generics is to parameterize types (control the types specifically restricted by formal parameters through different types specified by generics without creating new types). That is to say, during the use of generics,

The data type of the operation is specified as one parameter, which can be used in classes, interfaces and methods, which are called generic classes, generic interfaces and generic methods respectively.

Related terminology:

E in ArrayList is called a type parameter variable Integer in ArrayList is called the actual type parameter The whole is called ArrayList generic type The whole ArrayList is called a parameterized type ParameterizedType

The role of generics:

The code is more concise "no casting"

The program is more robust. "As long as there are no warnings at compile time, the runtime will not throw ClassCastException Exception of "

Readability and stability "When writing collections, the types are limited"


List<String> strlist = new ArrayList<String>();
        List<Integer> intlist = new ArrayList<Integer>();
​
        strlist.add("A");
        strlist.add("B");
        //strlist.add(123);// Compile error 
​
        for(String str:strlist){
            System.out.println(str);
            //A
            //B
        }
​// Join Java Develop and exchange samples: 7565848221 Blowing water and chatting 
        System.out.println(strlist.getClass());//class java.util.ArrayList
        System.out.println(intlist.getClass());//class java.util.ArrayList
        System.out.println(strlist.getClass()==intlist.getClass());//true

Generic erasure

Generics are provided to the javac compiler to qualify the input type of the collection, allowing the compiler to block the insertion of illegal data into the collection at the source code level. However, the class file generated by the compiler after compiling the java program with generics will no longer contain generic information, so that the running efficiency of the program will not be affected. This process is called "erasure".

The concept of generics was put forward by JDK5. Before JDK5, there was no generics, so it is necessary to build collections below JDK5. When you assign a collection with a generic attribute to an older version of the collection, the generic is erased, preserving the upper limit of the type parameter, Object. When we assign a collection without type parameters to a collection with type parameters, we will not report an error, just prompt "unchecked conversion (Unchecked assignment)", and even assign it to other different types of collections with generic characteristics, but we will still throw ClassCastException exceptions.


 // Type is erased, leaving the upper limit of the type, String The upper limit of is Object
        List list = strlist;
​
        List<String> stringList2 = list;
        List<Integer> intList2 = list;// You can also assign it to Integer Type, but when you think of this collection as a collection of Integer When the collection operation of, it will still throw ClassCastException Anomaly 
​
        for (Integer i:intList2){//java.lang.ClassCastException
            System.out.println(i);
        }

2. Definition and Use of Generics

2.1 Generic Classes\ Generic Interfaces

Generic class, generic interface is to define generics on classes or interfaces, and only when users use this class can the types be clearly defined. Our commonly used collections, List, Map < K,V > Stack... is a generic class. Generics defined on classes can be used in methods and variables of generic classes.

Because the type parameter variable T is only a placeholder in java generic type, which can only be used after passing parameters, that is, after creating instances, static variables and static methods containing generic types cannot be defined in generic classes, and errors will be reported cannot be referenced from a static context. Variables and methods that contain generic types in a generic class cannot be used until the instance is created and the type parameters passed are specified.


class Myset<T>{
    private T value;
    //public static T sval;//cannot be referenced from a static context
    public static int sval2;
​// Join Java Develop and exchange samples: 7565848221 Blowing water and chatting 
    public Myset(){
​
    }
​
    public Myset(T val){
        this.value = val;
    }
​
    public void setValue(T value) {
        this.value = value;
    }
​
    public T getValue() {
        return value;
    }
​
   /* public static T getSval(){//cannot be referenced from a static context
        return sval;
    }*/
}
       Myset<String> myset = new Myset<>();
       myset.setValue("12345");
       System.out.println(myset.getValue());//12345
​
       myset = new Myset<>("23");
​// Join Java Develop and exchange samples: 7565848221 Blowing water and chatting 
       System.out.println(myset.getClass());//class liwx.learning.Myset

2.2 Generic Methods


 public static  <T> void PrintArray(T [] arr){
        System.out.print("[");
        for(T t:arr){
            System.out.print(t+",");
        }
        System.out.println("]");
    }
Integer[]  a = {1,2,3,4,5,6,7};
PrintArray(a);//[1,2,3,4,5,6,7,]

2.3 Inheritance of Generic Classes

Subclasses of generic classes inherit in two ways

The subclass does not specify the parameter variables of the generic class, and the subclass is also a generic class Subclasses specify parameter variables of generic classes, and subclasses are not generic classes

// The subclass does not specify the parameter variables of the generic class, and the subclass is also a generic class 
class MyChiSet1<T> extends Myset<T>{
    public MyChiSet1(){
​
    }
    public MyChiSet1(T val){
        super(val);
    }
​// Join Java Develop and exchange samples: 7565848221 Blowing water and chatting 
}
// Subclasses specify parameter variables of generic classes, and subclasses are not generic classes 
class MyChiSet2 extends Myset<String>{
    public MyChiSet2(){
​
    }
    public MyChiSet2(String val){
        super(val);
    }
}

2.4 Wildcard Character? And its upper and lower limits

Wildcard character < ? > What is the difference between and type parameter variables? Wildcard character < ? > Is an argument rather than a type parameter, and List < ? > Logically, it is all List such as List, List, etc. < Specific type argument > The use of the parent class is more flexible than the type parameter T, but the passed wildcard usually performs many operations independent of the specific type. If the specific type-related operations are involved and the return value is involved, the generic method T is still needed.

When we use? Wildcard character, you can only call object-independent methods, not object-type-related methods. Because you don't know what the specific type is until it is used by the outside world.


// Although Object Is the base class for all classes , But List<Object> Logically and logically List<Integer> There is no inheritance relationship, and this method can only pass in List<Object> Data of type  
   public static void showOList(List<Object> list){
        System.out.println(list.size());
    }
    // Similarly, this method can only pass in List<Number> Type, and cannot be passed in List<Integer>
    public static void showList(List<Number> list){
        System.out.println(list.size());
    }// Join Java Develop and exchange samples: 7565848221 Blowing water and chatting 
    // Use wildcard characters ,List<?> Logically, it is all List<Number>,List<Integer>,List<String> The parent class of … can pass all List Type, but cannot be used in the List<?> Data of type performs operations related to specific types, such as add
    public static void showList2(List<?> list){
        System.out.println("<?>");
        System.out.println(list.size());
    }
    // Set the upper limit of wildcard characters, which can be passed in List<Number And Number Subclass of >
    public static void showNumList(List<? extends Number> list){
        System.out.println(list.size());
    }
   // Set the upper limit of wildcard characters ,List<? super Number> Can only be passed in List<Number And its parent class >
    public static boolean Compare(List<? super Number> list1,List<? super Integer> list2){
        return list1.size()>list2.size();
    }

   List<Integer> Intgetlist = new ArrayList<>();
        List<Number> Numberlist = new ArrayList<>();
        // Although Number Yes Integet Parent class of , But the incoming List They logically have no inheritance relationship 
        System.out.println(Intgetlist.getClass()==Numberlist.getClass());//true
​// Join Java Develop and exchange samples: 7565848221 Blowing water and chatting 
        //showList(java.util.List<java.lang.Number>)
        //List<Integer> And List<Number> There is no logical inheritance relationship, so it cannot be called 
        //showList(Intgetlist);//showList(java.util.List<java.lang.Number>)in FXtest cannot be applied to(java.util.List<java.lang.Integer>)
        showList(Numberlist);
​
       //public static void showList2(List<?> list)
        // Wildcard character List<?> Logically, it is all List< Specific parameter type > Method can pass in data of its subclass type 
        showList2(Intgetlist);
        showList2(Numberlist);
​
        // public static void showNumList(List<? extends Number> list)
        // When the wildcard upper limit is set, it can only be passed in List<Number And its subclasses > Data of 
        List<String> Stringlist = new ArrayList<>();
        showNumList(Intgetlist);
        showNumList(Numberlist);// Join Java Develop and exchange samples: 7565848221 Blowing water and chatting 
        //showNumList(Stringlist);//showNumList(java.util.List<? extends java.lang.Number>)in FXtest cannot be applied to(java.util.List<java.lang.String>)
​
​
        //public static boolean Compare(List<? super Number> list1,List<? super Integer> list2)
        // When the wildcard lower limit is set, List<? super Number> Can only be passed in List<Number And its parent class > Cannot pass in subclass Integer Adj. List , 
        //  And List<? super Integer> You can pass in its parent class Number Adj. List
        //Compare(Intgetlist,Numberlist);
        Compare(Numberlist,Intgetlist);

The use of wildcard logically restores the inheritance relationship of parameter parent class and subclass of data type passed in by generic class, and can also set the upper limit and lower limit of wildcard according to requirements.

List < ? > Logically all List < Specific parameter type > Can manipulate all List data List < ? extends Type > Set the upper limit of wildcard characters, and can operate on all subclasses of Type and Type List < ? super Type > Set the lower limit of wildcard character, which can operate on all parent classes of Type and Type

The above is the Java generic common interview questions (interview must ask) details, more information about Java generic interview questions please pay attention to other related articles on this site!


Related articles: