Java programming ideas Chapter_14 type information

Keywords: Java Programming JDK Android

There is a noun around this chapter: Run-time Type Identification runtime type recognition

Someone knows that the author introduced this concept from C++, but it doesn't matter. Understanding and concatenating this chapter is the most important thing

The content of this chapter is actually for the type of information service, the main content is

Class Object

Question:

1. What is the process of creating Class objects

2. What are the ways Class objects are created and what are the differences between them

3. Use generics

Before you know the type information, you need to know the class object

To create a class object, you first need to look for the.Class file of this class. The class file you find will be loaded into memory as byte code, and then you can create all the objects of this class through the Class object in memory.

There are three ways to create objects in this chapter

First: via the new constructor

Second: Class cls = Class.forName("fully qualified name"); cls.newInstance();

The third type of Class cls =class:.class; cls.newInstance();

The second and third create objects through the virtual constructor newInstance(), which has two points to note: 1. interfaces cannot newInstance; 2. class must have empty constructors

What is the difference between these three ways, where other points of knowledge are involved?

1. Call a static method of a class, have you created an object

The answer is no, because there are no three ways to create objects, just load the.Class file into memory, initialize the class, and do not create objects.

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        A.print();
    }
}
class A{
    static{
        System.out.println("static Static block");
    }
    
    public A(){
        System.out.println("Construction method");
    }
    
    public static void print(){
        System.out.println("Print class A");
    }
}

The printed results are as follows:

static block
Print class A

2. Is there a difference between class.forName ("fully qualified name") and.class

In contrast, Class.forName actively loads static method blocks, whereas.class does not, and.class does not initialize static methods or non-constant static fields until they are first referenced

public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {
            Class.forName("chapter_14.A");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

Print: static block

public static void main(String[] args) {
        // TODO Auto-generated method stub
        Class cls = A.class;
}

No Print

To put it aside, why do we usually see static constants being accessed like this

public static final int CONSTANT = 5;

Instead of

public static int CONSTANT = 5;

The reason is that static final is a compile-time constant and the class. CONSTANT can be read without initializing the class

 

The significance of introducing generics is simply to provide compile-time checks. Chapter 15 focuses on generics, which provide several concepts

Unlike ordinary.class, generic newInstance() returns the exact type of the object

class A{}

class B extends A{}

Class<A> clsA = A.class;
A objA = clsA.newInstance();

What about superclasses?

Class<? super B> clsA = B.class.getSuperclass();
Object objA = clsA.newInstance();

Superclass is not an exact type, it's just an Object

What about inheritance classes?

Class<? extends A> clsB = B.class;
A objA = clsB.newInstance();

At this point, we get the type of parent class. In the next learning, we will often create objects in this way, which is polymorphic and type information.

2. Check before type conversion

Question:

1. Significance and method of checking before type conversion

Avoid ClassCastException by explicit downward transition

There are three common ways to check, instanceof, isInstance, isAssignableFrom

For instance:

class A implements Iface{}

class B extends A{}

interface Iface{}

The first instance of

//Class checks the type of object instantiated by its own class
Class<? super B> clsA = B.class.getSuperclass();
Object objA = clsA.newInstance();
System.out.println(objA instanceof A);//true

//Class Check Subclass Instantiation Object Type
Class clsB = B.class;
Object objB = clsB.newInstance();
System.out.println(objB instanceof A);//true

//Interface check implements the type of class instantiation object
System.out.println(objA instanceof Iface);//true
System.out.println(objB instanceof Iface);//true

Second: isInstance

Class<? super B> clsA = B.class.getSuperclass();
Object objA = clsA.newInstance();
            
Class clsB = B.class;
Object objB = clsB.newInstance();
//Class Class Object Check Instantiated Object of Class itself
System.out.println(clsA.isInstance(objA));//true
System.out.println(clsB.isInstance(objB));//true
//Class Class Instantiated object of object check subclass
System.out.println(clsA.isInstance(objB));//true
            
            
//Interface Class Object Check Instantiated Object of Implementation Class
Class clsIface = Iface.class;
System.out.println(clsIface.isInstance(objA));//true
System.out.println(clsIface.isInstance(objB));//true

Third isAssignable From

Class<? super B> clsA = B.class.getSuperclass();
Object objA = clsA.newInstance();
            
Class clsB = B.class;
Object objB = clsB.newInstance();
//Class Class Object check class itself Class object
System.out.println(clsA.isAssignableFrom(clsA));//true
            
//Class Class Object Check Subclass Class object
System.out.println(clsA.isAssignableFrom(clsB));//true
            
//Interface Class Object Check Implementation Class Class object
Class clsIface = Iface.class;
System.out.println(clsIface.isAssignableFrom(clsA));//true
System.out.println(clsIface.isAssignableFrom(clsB));//true

To summarize these three ways, here is the picture below.

On the other hand, type checking also illustrates the relationship between classes and classes, and between classes and interfaces.

3. Registered factories

Question:

1. What's the use of registering a factory?

Registered factories combine factory method design patterns with additions, whether in this chapter or in relation to type information, to add objects to the base class that implement the class, but only according to the factory design pattern. The benefit of doing so is to "avoid damage to the structure caused by newly added data".The examples in this chapter are impressive and very good, and if I have good examples, I will always link them

4. Empty Objects

Question:

1. What is an empty object

2. Meaning of using empty objects

Usually, an empty object is a singleton that has properties that cannot be modified

Assuming that a variable of a class is an empty object by default, if you want to change the properties of this variable, you need to re-create an object to replace the empty object. It feels like I'm saying nonsense, but this is the nature of an empty object. Consider the following code

interface Null{}

class Person{
    
    private final String first;
    private final String last;
    private final String address;
    public Person(String first, String last, String address) {
        super();
        this.first = first;
        this.last = last;
        this.address = address;
    }
    @Override
    public String toString() {
        return "Person [first=" + first + ", last=" + last + ", address=" + address + "]";
    }
    
    static class NullPerson extends Person implements Null{

        private NullPerson(){
            super("None", "None", "None");
        }
        
        @Override
        public String toString() {
            return "NullPerson";
        }
    
    }
    
    public static final Person NULL = new NullPerson();
}

This code is copied from the empty object section of Java programming thought, and there is another point of knowledge: not every class will have a default empty constructor, like the Person class above, there is no empty constructor. The problem is that the constructor's parameters are modified with final, so you can explore it.

5. Reflection

1. What is the reflection mechanism?

2. How to use reflection mechanism through dynamic proxy

Reflection is a program that opens and checks.Class files at run time, so reflection is dynamic, and the concept of reflection is supported in JDK using the Class class and java.lang.reflect class libraries

Reflection is used because there are attributes of certain classes, methods do not have package access, and we have to access them to do something

As you can imagine, package access does not work for reflection, including privates, private internal classes, and anonymous internal methods

Examples of applications to reflection are EventBus for component communication in android, which can be downloaded to see the source code

Reflection can also be used for dynamic proxies (to say more, dynamic proxies are essentially type information) The main code is copied from the book

public class Test {

    public static void main(String[] args) {
        A objA = new A();
        
        Iface iface = (Iface) Proxy.newProxyInstance(Iface.class.getClassLoader(), 
                new Class[]{Iface.class}, new DynamicProxyHandler(objA));
        doSomething(iface);
    }
    
    public static void doSomething(Iface iface){
        iface.doSomething();
    }
}

class A implements Iface{
    @Override
    public void doSomething() {
        System.out.println("A doSomething");
    }
}

interface Iface{
    
    public void doSomething();
    
}

//All calls will be redirected to this single processor
class DynamicProxyHandler implements InvocationHandler{

    private Object proxied;
    
    public DynamicProxyHandler(Object proxy){
        proxied = proxy;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // TODO Auto-generated method stub
        return method.invoke(proxied, args);
    }
}

There are three things to note here: 1. Redirect a single processor, what is the object invoked; 2. Create an iface must be an interface object, and the second parameter to pass to create an interface object is the Class array, which contains the interface name.class for all proxied; 3. Relationship between dynamic proxies and type information

Summary: Type information is essentially about upward or downward transition

Posted by betportal on Tue, 21 May 2019 10:56:57 -0700