Author – Huanhuanlu, support the original, reproduced please indicate the source, thank you for cooperation. The original link: http://www.jianshu.com/p/aaf8594e02eb

Companies value the ability to learn: fundamentals matter

# # # JDK1.5 new features

  1. The generic
  2. foreach
  3. Automatic unpacking and packing
  4. The enumeration
  5. Static import
  6. Metadata
  7. The thread pool
  8. annotations

# # # JDK1.6 new features

  1. Desktop class and SystemTray class
  2. Use JAXB2 to map objects to XML
  3. StAX
  4. Use the Compiler API
  5. Lightweight Http Server API
  6. Pluggable Annotation Processing API
  7. Develop Console programs with Console
  8. Support for scripting languages
  9. Common Annotations

# # # JDK1.7 new features

Language support for collection classes; 2 automatic resource management; 3 improved generic instance creation type inference; 4 numeric literals underscore support; 5 String is used in switch. 6 Binary literals; Simplify variable parameter method calls.

# # # JDK1.8 new features

  1. The default method of an interface, that is, the interface can have implementation methods
  2. Functional interfaces and static imports
  3. Lambda expressions
  4. Accessing local variables

Static import: new in JDK1.5

Import static java.lang.math.abs; // static java.lang.math.abs; Import static java.lang.Math.*; // Static java.lang.Math. Public static void main(String[] args) {// Use system.out.println (abs(-100)); } public static void abs() {} public static void abs() {}Copy the code

### mutable parameters

Before variadic arguments, the only way to implement variadic arguments is through method overloading, which is a lot of work.

Before variable parameters are available, methods to implement variable parameters can be implemented through Obiect[].

  1. Mutable arguments can only be placed last in the argument list

  2. The compiler implicitly creates arrays for mutable arguments, so mutable arguments can be used as arrays

     public static int add(int x, int... args) {
         int sum = x;
    
         for (int i = 0; i < args.length; i++) {
             sum += args[i];
         }
    
         return sum;
     }
    Copy the code

### Enhance the for loop

Type arg: the object to iterate over) {}Copy the code

### Automatic packing and unpacking of basic data types

Integer i1 = 1000; Integer i2 = 1000; Println (i1 + 10); system.out.println (i1 + 10); Println (i1 == i2); system.out.println (i1 == i2);Copy the code

-128 to 127 will be buffered to save memory. This is the application of the Meta-design pattern, internal state/External state (variable)

# # # enumeration

#### Why use enumerations? For example, if we want to use 1-7 for Monday to Sunday, the usual thing to do is to define a class and provide some public static constants, such as:

public class WeekDay {
    public static final int SUN = 1;
    public static final int MON = 2;
}
Copy the code

However, when we use it, some people may not want to ignore this detail, such as passing in 1 directly (maybe he thinks 1 is for Monday), so there will be some unexpected problems when running.

To solve this problem, Java 5 reintroduced enumerations to ensure that a variable can take only one of the specified values, and that the passed values are known at compile time.

#### Simulation of enumeration:

/** * Manually implement enumeration classes * 1. Constructors must be private * 2. Provide public static member variables to represent enumerations, and use anonymous inner subclasses to generate objects * 3. Public static WeekDay MON = new WeekDay(0) {@override public WeekDay next() { return SUN; } @Override public String toString() { return "SUN"; }}; public static WeekDay SUN = new WeekDay(1) { @Override public WeekDay next() { return MON; } @Override public String toString() { return "MON"; }}; private int num; Private WeekDay(int num) {this.num = num;} private WeekDay(int num) {this.num = num; } // Public abstract WeekDay next(); }Copy the code

Some of the key points are given in the comments above, and this is the only way to generate WeekDay objects when used. (Enumerations actually generate objects inside.)

WeekDay weekDay = WeekDay.MON;
weekDay.next();
Copy the code

Implementation of enumeration

Public enum WeekDay {// Enumeration object must be first, anonymous inner class can be created with arguments, must implement the parent class abstract method MON(1) {public WeekDay next() {return SUN; } }, SUN(2) { public WeekDay next() { return MON; }}; private int num; // Enumeration constructors are private by default and can take arguments WeekDay(int num) {this.num = num; } public abstract WeekDay next(); }Copy the code

Enumeration uses, and some enumeration-specific methods:

WeekDay w = weekday.mon; WeekDay w = WeekDay. Println (w); // To print the enumeration directly is to call toString System.out.println(w); // Prints the name of the enumeration, actually prints the short name of the class w.gettClass ().getSimplename () system.out.println (w.name()); // Prints the position of the enumeration object in the enumeration, 0 starts counting system.out.println (w.ordinal()); Println (weekday.valueof ("MON")); // Use a string to get or get the enumeration object System.out.println(weekday.valueof ("MON")); For (WeekDay value: weekday.values ()) {system.out.println (value); }Copy the code

#### Special uses of enumerations – the singleton pattern can be implemented simply with enumerations

### Reflection – JDK1.2 has it

Learn about the Class Class, the basis of reflection

The Class used to describe Java classes is Class.

Each Class occupies an area of memory in the Java Virtual machine, which contains the bytecode (Class) of that Class.

####Class bytecode retrieval:

Class object. GetClass class. ForName (" The full name of the class ");Copy the code

Closely related to reflection is the forName method, which fetches bytecode from the class name. The first two have been loaded on virtual machines. The forName method is dynamically loaded when no bytecode has been loaded in the virtual machine. When already loaded, directly reuse loaded.

#### Nine pre-defined basic Class bytecodes

Eight data types, plus void has its own bytecode. Here are some examples:

Class<Integer> type = Integer.TYPE;
Class<Integer> integerClass = int.class;
Class<Void> voidClass = Void.class;
Copy the code

Example:

public static void main(String[] args) throws Exception { Class<? > c1 = Class.forName("java.lang.String"); Class<String> c2 = String.class; Class<? extends String> c3 = new String("123").getClass(); // Return the same bytecode, so == system.out.println (c1 == c2); System.out.println(c2 == c3); System.out.println(int.class.isprimitive ()); System.out.println(int[].class.isPrimitive()); Println (int[].class.isarray ()); system.out.println (int[].class.isarray ()); }Copy the code

#### The concept of reflection

To sum up: Reflection is the mapping of components of a Java class through Java’s reflection API into corresponding Java classes, which can then be used. Methods, constructors, member variables, types, packages, etc. Here are the explanations.

Constructor class

Get all the constructors

Constructor<? >[] constructors = Class.forName("java.lang.String").getConstructors();Copy the code

Returns one of the constructors for the specified argument:

Constructor<? > constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);Copy the code

Create an object

String s = (String) constructor.newInstance(new StringBuffer("abc")); System.out.println(s.charAt(2)); You can also call a no-argument construct directly, String s = (String) class.forName (" java.lang.string ").newinstance ();Copy the code

The Class newInstance method caches Constructor. Use reflection with caution because it greatly reduces system performance, is time-consuming for computers, and is prone to runtime exceptions.

Field objects

Field represents a member variable in the class

For example, we have a test class Point

public class Point { public int x; private int y; protected int z; public Point(int x, int y, int z) { this.x = x; this.y = y; this.z = z; }}Copy the code

So, we can use the emission mechanism to get the member variables of an object in the virtual machine and get their values

Point point = new Point(1, 2, 3); Field x = point.getClass().getField("x"); System.out.println(x.get(point)); Field y = point.getClass().getField("y"); Field y = point.getclass ().getfield ("y"); // Private variables need to be obtained by using getDeclaredField. Field y = point.getClass().getDeclaredField("y"); y.setAccessible(true); System.out.println(y.get(point));Copy the code

For example, change a in all String values to * :

public class Reflecttest1 { public static void main(String[] args) throws Exception { Test test = new Test(); changeString(test); System.out.println(test); } private static void changeString(Object obj) throws Exception { for (Field field : Obj.getclass ().getFields()) { == if (field.getType() == string.class) {String oldV = (String) field.get(obj); String newV = oldV.replace('a', '*'); field.set(obj, newV); }}}}Copy the code

# # # # Method class

String a = "0123"; Method charAt = a.getClass().getMethod("charAt", int.class); Println (charat.invoke (a, 1)); charat.invoke (charat.invoke (a, 1));Copy the code

Call the main method of the specified object, noting the problem of passing an array of strings

Due to variable-length arguments, the JDK unpacks arrays passed in for compatibility with versions below 1.4. Therefore, the comment code will report arguments that do not match.

The solution is

1, use the Object array wrapper layer, tell the compiler, can be unpacked, but after unpacking is a String array.

2, phase cast to Object, tell the compiler, do not unpack.

public class ReflectTest3 { public static void main(String[] args) throws Exception { Method mainMethod = Class.forName("com.nan.test.T").getMethod("main", String[].class); // mainMethod.invoke(null, new String[]{"123"}); mainMethod.invoke(null, new Object[]{new String[]{"123"}}); mainMethod.invoke(null, (Object) new String[]{"123"}); } } class T { public static void main(String[] args) { for (String s : args) { System.out.println(s); }}}Copy the code

#### Array type

Arrays of the same dimension and element type, belonging to the same Class type.

Example:

int[] a1 = new int[3];
int[] a2 = new int[4];
int[][] a3 = new int[3][4];
String[] a4 = new String[3];

System.out.println(a1.getClass());
System.out.println(a2.getClass());
System.out.println(a3.getClass());
System.out.println(a4.getClass());
Copy the code

Output result:

class [I
class [I
class [[I
class [Ljava.lang.String;
Copy the code

Where [represents the array type and I represents the element type (int)

Arrays of the eight basic types cannot be converted to Object arrays. Therefore, the following statement is illegal:

Object[] objects = a1; // Since a one-dimensional array of basic type cannot be treated as an Object, it can only be treated as an array Object. // Therefore, the output is the value of the Object of the array, not its contents. Println (arrays.asList (a1)); System.out.println(arrays.aslist (a4));Copy the code

# # # # array

You can manipulate an array by reflection, because it’s an Object array, so you can’t determine whether the entire array is of the same type, so you can only determine the type of each item.

Private static void printObj(Object o) {if (o.geclass ().isarray ()) {private static void printObj(Object o) {if (o.geclass ().isarray ()) Array.getLength(o); for (int i = 0; i < length; i++) { Object item = Array.get(o, i); System.out.println(item); } } else { System.out.println(o); }}Copy the code

Equals vs. hashCode

  1. If two instances of a class are equals, hashCode must also be equal, and vice versa.
  2. A hashCode only makes sense in a hash set, such as a hashMap, a hashSet, etc. When an object is stored in or removed from a hash collection, contains calls, etc., the hash value is calculated to determine the storage area in which the object should reside, and then the equals method is used to determine whether the object is duplicated in the storage area. (Hash equals, equals can not be equal)

In general, both need to be overridden, and after the object has been inserted into the hash set, do not change the value of the object associated with the hash calculation, because this will cause the hash set to change the value of the object, and the object cannot be cleaned up, resulting in a memory leak.

HashSet<Point> set = new HashSet<>(); Point p0 = new Point(1,2,3); Point p1 = new Point(1,2,3); set.add(p0); // If you override hashCode and equals, the object can be inserted into set.add(p1); // The value changed and the object could not be removed (found), resulting in a memory leak. set.remove(p0); System.out.println(set.size());Copy the code

A regular non-hash collection, such as an ArrayList, only holds references to data that can be repeated.

What Java reflection does – Implements framework functionality

Differences between frameworks and tools:

Same: all provided by others

Difference:

  1. Utility classes are called by the user
  2. The framework is to invoke user-supplied classes

Such as:

  1. The framework provides configuration files that users can configure, such as class names
  2. Read the configuration file of the user
  3. Load the corresponding class by reflection and use it dynamically

Reading configuration files

InputStream is = new FileInputStream(" file directory "); Properties properties = new Properties(); properties.load(is); String value = properties.getProperty("key");Copy the code

Most configuration files are loaded using the class loader.

// The class loader can read the configuration file with the class. Here is the relative path to the class. If/represents an absolute path, write the full/package name... InputStream res = ReflectTest3. Class. GetResourceAsStream (" directory "); / / InputStream res = ReflectTest3. Class. GetClassLoader () getResourceAsStream (" directory "); properties.load(res);Copy the code

Introspection, and Java Beans

Java beans: Java classes that conform to certain GET and SET rules

The property name of the Java bean is get, the set method is removed, and the remaining — if the second letter is also lower case, then — the initial letter needs to be lower case

Such as:

getAge-->age

setCPU-->CPU
Copy the code

Introspection: APIS for manipulating Java Bean objects

Bean b = new Bean(1); String propertyName = "x"; // The normal method x--> x--> getX--> call // Now use introspection method to get method, Set descriptor pd = new PropertyDescriptor(propertyName, b.goetclass ()); Method getXMethod = pd.getReadMethod(); System.out.println(getXMethod.invoke(b, null));Copy the code

The more cumbersome way to write it is to do it via BeanInfo

BeanInfo beanInfo = Introspector.getBeanInfo(b.getClass()); PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor p : pds) { if (p.getName().equals("x")) { Method readMethod = p.getReadMethod(); readMethod.invoke(b, null); }}Copy the code

Note the Annotation

Little knowledge:

  1. Type name: adjective + noun
  2. Method name: verb + noun

#### Concept of annotations Annotations are actually a class, and writing annotations is actually an object that creates annotations. Annotations are the equivalent of marking a program. Javac compilation tools, development tools, and other programs can use reflection to see if there are any tags on your classes and various elements and do the same.

Tags can be added to packages, types (including classes, enumerations, interfaces), fields, methods, method parameters, and local variables.

Here are some common Java annotations:

Deprecated // Override // marks the method as a subclass overriding its parent class, telling the compiler to check SuppressWarnings // to remove the outdated delete lineCopy the code

#### Application structure diagram of annotations

Three classes are required:

Example:

Here’s a note:

import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Created by Administrator on 2016/9/16. */ @retention (retentionPolicy.runtime @target ({elementtype. METHOD, elementtype. TYPE}) public @interface A {}Copy the code

Annotation class:

@A
public class AnnotationTest {

}
Copy the code

Get annotations (by reflecting on AnnotationTest) :

Class<AnnotationTest> c = AnnotationTest.class; If (c.isanNotationPresent (a.class)) {A A = c.getAnnotation(a.class); }Copy the code

#### meta-annotations, which are used to add annotations to annotations

@target (elementType.method) // Declare where annotations can be used, pay particular attention to classes, enumerations, and interfaces. @retention (retentionPolicy.source) // Declare the annotation in what declaration cycle, Source code, class file, runtimeCopy the code

#### Note that multiple attributes need to be enclosed in braces:

@Target({ElementType.METHOD, ElementType.TYPE})
Copy the code

#### Annotation lifecycle

  1. SOURCE: Annotations are reserved for the SOURCE file stage. When Javac compiles the source file to a. Class file, the corresponding annotations are removed. Common Override and SuppressWarnings, for example, fall within the lifecycle of the SOURCE type because the annotations are useless once the code is compiled.
  2. CLASS: When the Java virtual machine loads bytecode into memory through the CLASS loader, the annotation is removed and therefore cannot be retrieved by reflection.
  3. RUNTIME: Annotations remain on top of the bytecodes in memory and can still be used by the virtual machine while running bytecodes. For example Deprecated, when a class is being used by someone else, it is loaded into memory, scanned from the binary code to see if it is obsolete, rather than checking the source code.

#### adds attributes for annotations

Supported data types for annotation parameters:

  1. All basic data types (int, float, Boolean, byte, double, char, long, short)
  2. Type String
  3. The Class type
  4. Enum type
  5. The Annotation type
  6. All of the above types of arrays

Example:

@retention (retentionPolicy.runtime) @target ({ElementType.METHOD, Elementtype.type}) public @interface A {String stringAttr(); Class value() default Object.class; int[] arrAttr(); Deprecated annoAttr() default @Deprecated; }Copy the code

Note the following when using annotations:

  1. When only value needs to be set (that is, only the value attribute or other attributes have been specified as default), you can directly write the value inside the parentheses without value, for example:

    @SuppressWarnings(“deprecation”)

  2. When the type is array, if there is only one element, you can omit the curly braces and write just one element.

Once the annotations have been obtained by reflection, they can be used as they please:

Class<AnnotationTest> c = AnnotationTest.class; if (c.isAnnotationPresent(A.class)) { A a = c.getAnnotation(A.class); System.out.println(a.stringattr ())); }Copy the code

The generic

# # # #

Generics are used in collections, reflection, and so on, eliminating the insecurity of casting, including the code phase and the run phase. Generics are for the compiler to see, let the compiler intercept the source program illegal input, after the compilation will remove the type information, to ensure the efficiency of the program. For parameterized generic types, the getClass method returns exactly the same value as the original type.

So after compiling, skip the compiler and use reflection to add other types of data to the collection, as shown in the following example:

List<Integer> list = new ArrayList<>(); List.getclass ().getMethod("add", object.class).invoke(list, "ABC "); System.out.println(list.get(0));Copy the code

#### Some terms about generics:

ArrayList<E> Generic type E type variable or type parameter in ArrayList<E> ArrayList<String> Parameterized type String Actual type parameter in ArrayList<String> <> in ArrayList<String> is read as type ofCopy the code
  1. With or without generics, the end result of the program is the same
  2. Parameterized types, regardless of the inheritance of type parameters

For example, the following line of code is incorrect because parent-child relationships are not considered:

List<Object> list1 = new ArrayList<String>();
Copy the code

Wildcards in generics?

Instead of Object, use? Represents any type. ? Wildcards can refer to various other parameterized types,? Wildcard variables are used primarily as references. Methods associated with type parameters (methods that have generic parameters in them) cannot be called when type parameters are not assigned.

Example:

public static void printSise(List<? > l) { l.add(new Object()); Object o = l.get(1); Object for (Object obj: l) {system.out.println (obj); // Return value is generic, but we can convert to Object for (Object obj: l) {system.out.println (obj); }}Copy the code

The upper and lower bounds of #### generics can be qualified with & to implement multiple interfaces

// List<? extends Number> l1 = new ArrayList<Integer>(); // List<? super Integer> l2 = new ArrayList<Object>();Copy the code

Examples of generics, and iterative approaches to various collections (mainly Maps) :

####1. Enhance the for loop to traverse the MAP, which is the most common and in most cases the most desirable way to traverse. Note: The for-each loop was introduced in Java 5 so this method can only be used in Java 5 or later. If you’re iterating over an empty map object, the for-each loop throws a NullPointerException, so you should always check for empty references before iterating.

Map<Integer, Integer> map = new HashMap<Integer, Integer>();

for (Map.Entry<Integer, Integer> entry : map.entrySet()) {

    entry.getKey();
	entry.getValue();

}
Copy the code

####2. Iterate over keys or values in a for-each loop. If you only need the keys or values in the map, you can iterate through keySet or values instead of entrySet. This method performs slightly better than entrySet traversal (10% faster), and the code is cleaner.

Map<Integer, Integer> map = new HashMap<Integer, Integer>();

For (Integer key: map.keyset ()) {} for (Integer value: map.values()) {}Copy the code

####3. Use iterators, which remove elements in an iteration.

Map<Integer, Integer> map = new HashMap<Integer, Integer>();

Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator();

while (entries.hasNext()) {

    Map.Entry<Integer, Integer> entry = entries.next();

    entry.getKey();
	entry.getValue());

}
Copy the code

####4. Traversal by key value is inefficient and is generally not used.

Map<Integer, Integer> map = new HashMap<Integer, Integer>();

for (Integer key : map.keySet()) {

    Integer value = map.get(key);

    System.out.println("Key = " + key + ", Value = " + value);

}
Copy the code

# # # # :

Use method 2 if only keys or values are required. If you are using a language version younger than Java 5 or want to delete entries during a runtime, you must use method three. Otherwise use method one (both key values).

#### introduces custom generics from C++ template functions

#### why generics in Java do not fully do what templates in C++ do:

Generics in Java are similar to templates in C++, but the similarity is limited to the surface. Generics in Java are basically implemented in compilers that perform type checking and inference, and then generate plain non-generic bytecode, a technique known as erasures. Because extending the virtual machine instruction set to support generics is considered unacceptable, it makes it difficult for Java vendors to upgrade JVMS. Therefore, different generic parameters do not constitute overloading.

  1. The actual type of a generic type cannot be a primitive type, only a reference type.
  2. A new type is declared after the modifier and before the return value type.
  3. You can have more than one type variable, separated by a comma.
  4. The name of a type parameter is usually named with an uppercase letter.
  5. The compiler does not allow direct new T arrays or objects.
  6. Exceptions can be represented by type variables, called parameterized exceptions, and are not used much.

Example:

private static <T> T[] swap(T[] arr, int i, int j) {
    T tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
    return arr;
}
Copy the code

#### parameter type inference (complex)

Type inference for type parameters: The process by which the compiler determines the actual type parameters of a generic method is called type inference. Type inference is relative to perceptual inference, and its implementation is a very complex process. Based on the type of parameter or return value actually passed when a generic method is called, as follows:

  1. When a type variable values in the parameter list of all the parameters and return values in a application class, so depending on the type of the actual application method is called when there to determine, this is easily deduced from feeling, namely direct depending on the type of parameters passed when calling methods or the return value to determine generic type parameters, such as: Swap (new String[3],3,4) –> static void swap(E[] a,int I,int j) –> static void swap(E[] a,int I,int j)
  2. When a variable of type is applied to multiple places in the entire argument list of all arguments and return values, it is easy to infer by intuition if the actual application type of multiple places corresponds to the same type when calling the method, for example: add(2,5) –>static T add(T a, T b)
  3. When a type variable in the parameter list of all parameters and return values are applied at many points along the, if a method is called when the practical application of several types of corresponding to the class of different types, and the return value is not used, the biggest type of intersection, then take more parameters, for example, the following statements is the Number of actual corresponding types, compiled no problem. Fill (new Integer[3],3.5f)–>static void fill(T[], T v)//Integer∩Float = Number
  4. When a type variable in the parameter list of all parameters and return values are applied at many points along the, if a method is called when the practical application of several types corresponding to different types, and use the return value, then give priority to the type of the return value, for example, the following statement corresponds to the actual type is Integer, compiler will report an error, Int x = add(3,3.5f) –>static T add(T a,T b) –>static T add(T a,T b)

#### defines the type of the generic type

  1. Method level (described above)

  2. Generic types (classes) : Multiple methods use the same type

    class A {

    }

Note that static methods in a class cannot contain generics of the object. But you can have generic static methods. Example:

Public static void add(T T) {} public static void add(T T T) {} Public static <E> void set(E E) {}}Copy the code

#### Difficulty: Extract the type of parameters in the method through reflection

Public static void main(String[] args) throws Exception {// Extract the parameter types of the Method using a reflection Method. Method Method = A.class.getMethod("test", List.class); / / its returns the parameters of a parameterized Type, the Type with the actual parameter types [] types = method. The getGenericParameterTypes (); ParameterizedType Type = (ParameterizedType) types[0]; // Get the primitive type (interface java.util.list) system.out.println (type.getrawType ()); / / get the type of the actual parameter types (class Java. Lang. String) System. Out. The println (the getActualTypeArguments () [0]). } public static void test(List<String> list) { }Copy the code

Introduction to class loaders

#### Parent-child relationship and jurisdiction of the class loader

Example: Get and print class loaders:

Public static void main(String[] args) {// Prints the class loader for the current thread System.out.println(Thread.currentThread().getContextClassLoader().getClass().getName()); / / first class by default by the current thread class loader for loading System. Out. The println (ClassLoaderTest. Class. GetClassLoader () getClass (). The getName ()); // The System is loaded by the BootStrap class loader, which is written in C/C++. BootStrap don't need other loader for the / / can't get the class in the Java level reference System. Out. The println (System. Class. GetClassLoader () = = null); }Copy the code

Class loaders delegate mechanism, equivalent to event passing in Android, prevents bytecode reloading.

#### Custom loader

Classloaders have two methods: loadClass and findClass. The loadClass method first looks for the parent loader, and if it does not find the parent loader, it returns the method. If it finds the parent loader, it calls the findClass method to load the class. To keep this process intact (the template method design pattern), we need to override the findClass method.

#### custom loader can encrypt and decrypt bytecode

Here are just a few key steps:

  1. Write a class that needs to be encrypted, and compile the.class file

  2. The.class file is encrypted using an encryption algorithm (such as xor with 0xFF), read in with an input stream, and output to the file with an output stream.

  3. Custom ClassLoader that inherits ClassLoader. Copy the findClass method, load the encrypted. Class, convert it to a byte array, and decrypt it. Use the following method of the ClassLoader to convert the class file to bytecode.

  4. Bytecode can be reflected through the way of newInstance and other use.

    // Get the class file converted to bytecode protected final class <? > defineClass(byte[] b, int off, int len)Copy the code

# # # agent

Add system functionality, such as exception handling, logging, runtime of computation methods, transaction management, and so on, to existing methods of multiple target classes that have the same interface (already developed or without source code). You can use proxies, and they have this advantage.

The JVM can dynamically generate bytecode for classes at run time, and such dynamically generated classes are often used as proxies, called dynamic proxies. JVM generated classes must implement one or more interfaces, so JVM generated classes act as proxies for target classes with the same family.

The CGLIB library can dynamically generate a subclass of a class, and a subclass of a class can also be used as a proxy class for that class, so if you want to generate a dynamic proxy class for a class that does not implement an interface, you can use this library.

###AOP is oriented to the concept of faceted programming

#### Aspect Oriented programming (AOP is the acronym of Aspect Oriented Program). At runtime, the idea of dynamically cutting code into the specified method and location of a class is Aspect Oriented programming. Generally speaking, code snippets that cut into specified classes and methods are called facets, and which classes and methods to cut into are called pointcuts. With AOP, we can change the behavior of an object by taking the code shared by several classes and pulling it into a slice until we need to cut into it. In this way, AOP is really just a complement to OOP. OOP divides classes horizontally, while AOP adds specific code to objects vertically. With AOP, OOP becomes three-dimensional. With the addition of a time dimension, AOP transforms OOP from two-dimensional to three-dimensional, from flat to solid. Technically, AOP is basically implemented through a proxy mechanism. AOP is a milestone in the history of programming and a useful complement to OOP programming.

Example # # # #

Using the reflection API, the JVM dynamically generates proxy classes for the Collection interface

// Using the reflection API, the JVM dynamically generates the proxy Class<? > clazzProxy0 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class); // Enter the name of the dynamically generated class system.out.println (clazzProxy0.getName()); PrintConstructor (clazzProxy0); PrintMethod (clazzProxy0); / / / / can't use this class to build object using the no-arg constructor, because the proxy class has only one parameter in the constructor. / / clazzProxy0 newInstance (); Constructor<? > constructor = clazzProxy0.getConstructor(InvocationHandler.class); Collection collection = (Collection) constructor.newInstance(new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return null; }});Copy the code

Generating a proxy class object requires passing in an InvocationHandler object. The invocation of the proxy class’s method triggers the distribution of the InvocationHandler. The InvocationHandler internally calls the methods of the object of the proxy class and inserts some specified functionality.

Below is the function that prints all constructors and methods

private static void printMethod(Class<? > clazz) {system.out.println (" all methods "); for (Method m : clazz.getMethods()) { StringBuilder builder = new StringBuilder(m.getName()); builder.append("("); Class[] types = m.getParameterTypes(); for (Class<? > t : types) { builder.append(t.getName()).append(","); } if (types.length ! = 0) { builder.deleteCharAt(builder.length() - 1); } builder.append(")"); System.out.println(builder.toString()); } } private static void printConstructor(Class<? > clazz) {system.out.println (" all constructors "); for (Constructor c : clazz.getConstructors()) { StringBuilder builder = new StringBuilder(c.getName()); builder.append("("); Class[] types = c.getParameterTypes(); for (Class<? > t : types) { builder.append(t.getName()).append(","); } if (types.length ! = 0) { builder.deleteCharAt(builder.length() - 1); } builder.append(")"); System.out.println(builder.toString()); }}Copy the code

In one step:

// In one step, Access to the Proxy class and generate the Collection object collection1 = (Collection) Proxy. NewProxyInstance (Collection. Class. GetClassLoader (), new Class[]{Collection.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return null; }});Copy the code

The following is a practical example of inserting ads at the time of each method call:

/** * Created by Administrator on 2016/9/18. */ public class ProxyTest1 {private static ArrayList<String> target = new ArrayList<>(); Public static void main(String[] args) { Access to the Proxy class and generate the object Collection Collection = (Collection) Proxy. NewProxyInstance (Collection. Class. GetClassLoader (), new Class[]{Collection.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {system.out.println ("---- advertising start ----"); Object returnVal = method.invoke(target, args); System.out.println("---- AD end ----"); return returnVal; }}); collection.add("aad"); collection.add("aad"); collection.add("aad"); collection.add("aad"); System.out.println(collection.size()); }}Copy the code

Of course, we want to invoke something that the user (configuration) enters after the framework is complete, so we need to provide the interface again:

public interface Advice {

    void before(Object proxy, Method method, Object[] args);

    void after(Object proxy, Method method, Object[] args);
}
Copy the code

As shown above, for convenience, the interface provides only two simple methods to execute before and after the method.

We then also wrap the method of getting the proxy object so that the user passes in only the implementation class of the interface.

Public class ProxyTest1 {private static ArrayList<String> target = new ArrayList<>(); Public static void main(String[] args) { Collection = (Collection) getProxyInstance(collection.class, new Advice() { @Override public void before(Object proxy, Method method, Object[] args) {system.out.println (method.getName() + "start executing "); } @Override public void after(Object proxy, Method method, Object[] args) {system.out.println (method.getName() + "end execution "); }}); collection.add("aad"); collection.size(); } private static Object getProxyInstance(Class<? > clazz, Advice advice) { return Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { advice.before(proxy, method, args); Object returnVal = method.invoke(target, args); advice.after(proxy, method, args); return returnVal; }}); }}Copy the code

Note that all interface methods are distributed to the InvocationHandler, but only toString, Equals, and hashCode methods inherited from objects are distributed to the InvocationHandler.

The difference between String, StringBuilder, and StringBuffer

  1. Comparison in execution speed: StringBuilder > StringBuffer

  2. StringBuffer and StringBuilder, they’re String variables, they’re mutable objects, and whenever we use them to manipulate a String, we’re actually operating on an object, rather than creating objects to manipulate like a String, so it’s faster.

  3. StringBuilder: StringBuffer: thread-safe

    The JVM cannot guarantee that the StringBuilder operation is safe when used by multiple threads in the StringBuffer, although it is the fastest, but it can guarantee that the StringBuffer will operate correctly. Of course, most of the time we’re doing it in a single thread, so most of the time it’s recommended to use StringBuilder instead of StringBuffer because of the speed.

Summary of the use of the three:

  1. If you want to manipulate a small amount of data, use = String
  2. Single thread manipulation of large amounts of data in string buffer = StringBuilder
  3. Multithreaded manipulation of large amounts of data in string buffers = StringBuffer

The difference between ###Overload and Override

  1. Overloading is when different functions use the same function name but have different numbers or types of arguments. Call different functions based on their arguments.

  2. Overwriting (also known as overwriting) is the reimplementation of a virtual function in the base class in a derived class. That is, the function name and parameters are the same, but the implementation body of the function is different.

  3. Hiding is when a function in a derived class hides a function with the same name in the base class.

  4. Overriding and Overloading methods are different manifestations of Java polymorphism. Overriding is a form of polymorphism between superclasses and subclasses, and Overloading is a form of polymorphism within a class.

    Override (rewrite)

    1. The method name, parameter, and return value are the same. 2. Subclass methods cannot reduce the access rights of their parent methods. 3. A subclass method cannot throw more exceptions than a superclass method (but a subclass method may not). 4. Exists between a parent class and a child class. 5. Methods defined as final cannot be overridden.Copy the code

    They will overload.

    1. At least one parameter type, number, or sequence must be different. 2. Do not overload a method name that only returns different values. 3. Exist in the parent class and child class, same class.Copy the code

==, hashCode, equals

  1. Primitive data types, also known as primitive data types. Byte, short, char, int, long, float, double, Boolean comparison between them, the double equal sign (= =), and compare their values.
  2. == == == == == == == So the result is the same as the double equal sign (==).
  3. When putting an object into a collection, we first determine whether the hashcode value of the object to be put into the collection is equal to the hashcode value of any element in the collection. If not, we directly put the object into the collection. If hashCode is equal, then equals determines whether the object is equal to any other object in the collection. If equals determines otherwise, the element is added directly to the collection.

Rules:

  1. If two objects are equal according to equals(), then calling the hashCode method of either object must produce the same integer result.
  2. If two objects are not equal according to equals(), then calling the hashCode method of either object does not necessarily produce the same integer result. But programmers should be aware that it is possible to improve hash table performance by producing radically different integer results for unequal objects.

Difference between HashMap and HashTable

  1. A HashMap can be almost equivalent to a Hashtable, except that a HashMap is non-synchronized and can accept NULL (a HashMap can accept null keys and values, whereas a Hashtable cannot).
  2. HashMap is non-synchronized while Hashtable is synchronized, which means that Hashtable is thread-safe and multiple threads can share a Hashtable; Without proper synchronization, multiple threads cannot share a HashMap. Java 5 provides ConcurrentHashMap, which is an alternative to HashTable and is more extensible than HashTable.
  3. They use different iterations.

Sychronized means that only one thread can change the Hashtable at a time. This means that any thread that updates the Hashtable must acquire the lock first, and any other thread that updates the Hashtable cannot acquire the lock again until the lock is released.

HashMap can be synchronized with the following statement: the Map m = Collections synchronizeMap (HashMap);

Conclusion:

There are several major differences between hashTables and HashMaps: thread-safety and speed. Use Hashtable only when you need complete thread-safety, and ConcurrentHashMap if you use Java 5 or above.

Difference between ArrayList and Vector

  1. Vector is thread-safe, that is, thread-synchronized between its methods, whereas ArrayList is line-unsafe.
  2. Data growth: ArrayList and Vector both have an initial capacity. When the number of elements stored in them exceeds the capacity, the storage space of ArrayList and Vector needs to be increased. Instead of adding one storage unit, the storage space of ArrayList and Vector needs to be increased. The number of additional storage units must be balanced between memory utilization and program efficiency. Vector defaults to double, whereas ArrayList’s growth strategy is not specified in the documentation (1.5 times as seen from the source code). Both ArrayList and Vector can set the initial size of the space. Vector can also set the size of the space to grow. ArrayList provides no method to set the size to grow.

### 4 Ways to create objects in Java bookmark 4 ways to create objects in Java

  1. Create objects with the new statement, which is the most common way to create objects.
  2. By means of reflection, invokes the Java. Lang. Class or Java. Lang. Reflect. The Constructor Class newInstance () instance methods.
  3. Call the clone() method of the object.
  4. By means of the deserialization, search invokes the Java. IO. Object ObjectInputStream readObject () method.

Static variables, static code block loading process and timing? A: Static variables are created when the class loader loads the class into the JVM, and memory is allocated when static variables are loaded. The code for a static code block is executed only once when the class is first initialized, the first time it is used.

##MVC, MVVP, MVP design mode

  1. MVC: The MVC coupling is still relatively high, the View can directly access the Model
  2. MVP: Model, View, Presenter, View can not directly access Model
  3. MVVM: Bidirectional Binding of View and Model, similar to data-binding

###JAVA container architecture diagram

If you feel that my words are helpful to you, welcome to pay attention to my public number:

My group welcomes everyone to come in and discuss all kinds of technical and non-technical topics. If you are interested, please add my wechat huannan88 and I will take you into our group.