Java ------ JUnit, annotation, Class Loader
JUnit Software Testing Technology (tools)
Create a dedicated user-tested package structure in the project.
In Junit, you can Run a method using the @ Test annotation (place the cursor over the method name to be Run, right-click the method, select Run As, and then select JUnit Test ).
The advantage of this is that you do not need to add the test code to the main code to avoid code redundancy. In addition, a test class can test multiple functions without the main method.
I. Junit annotations
The @ Test annotation must meet the following conditions:
1) it must be a non-static method without parameters.
2) the class added with @ Test annotation must have a public structure without Parameters
package junit.test;import org.junit.Test;import junit.UserDaoImpl;public class TestUserDaoImpl {@Testpublic void testFun1(){new UserDaoImpl().fun1();}@Testpublic void testFun2(){new UserDaoImpl().fun2();}@Testpublic void testFun3(){new UserDaoImpl().fun3();}}
Ii. JUnit test example
1. After running, you can view the running time and result information in the Junit window.
2. The running result of the tested program appears on the Console.
3. Other annotations in JUnit
@ BeforeClass, @ AfterClass, @ Before, @ After
package junit.test;import junit.UserDaoImpl;import org.junit.AfterClass;import org.junit.BeforeClass;import org.junit.Test;public class TestUserDaoImpl2 {static UserDaoImpl obj = null;@Testpublic void testFun1(){obj.fun1();}@BeforeClasspublic static void init(){obj = new UserDaoImpl();System.out.println(111111111111);}@Testpublic void testFun2(){obj.fun2();}@Testpublic void testFun3(){obj.fun3();}@AfterClasspublic static void finish(){obj = null;System.out.println(clearing....);}}
Result: 111111111111
Fun1 ......
8787
Fun2 ......
Fun3 ......
Clearing ....
Annotation (Annotation)
I. Metadata
Metadata is the data of data. That is to say, metadata describes data. Like a field in a data table, each field describes the meaning of the data under this field.
Metadata can be used to create documents, track code dependencies, and even perform basic compile-time checks. Many metadata tools, such as XDoclet, add these features to the core Java language and are currently part of the Java programming function.
In general, the benefits of metadata are divided into three types: Documentation, compiler checks, and code analysis. Code-level documents are most often referenced. Metadata provides a useful method to indicate whether the methods depend on other methods and whether they are complete.
Determines whether the class must reference other classes.
2. What is Annotation
The annotation in Java is the metadata of the Java source code, that is, the annotation is used to describe the Java source code. The basic syntax is: @ followed by the annotation name.
3. pre-defined annotations in Java (three pre-defined annotations in the Java. lang Package)
① Override: Specifies whether a method correctly overwrites its parent class.
② Deprecated: indicates that this class member is no longer recommended. It is a tag annotation.
③ SuppressWarnings: used to suppress warning information.
Iv. Custom annotations
The syntax for custom annotation is very simple. It is similar to the definition interface, but only adds the @ symbol before the name.
1. The simplest custom Annotation
public @interface MyAnno {}
2. Use this Annotation
@MyAnnopublic class UserModel{}
3. Add a member for the Annotation
// Define public @ interface MyAnno {public String schoolName ();}
// Use @ MyAnno (schoolName = People's Republic of China) public class UserModel {}
4. Set the default value
// Define public @ interface MyAnno {public String schoolName () default People's Republic of China ;}
// Use 1 @ MyAnnopublic class UserModel {}
// Use 2 @ MyAnno (schoolName = Java master) public class UserModel {}
5. Annotation
☆Specify the Target
Before learning how to use Target, you need to know another class. This class is called ElementType (learn through API details), which is actually an enumeration. This enumeration defines different program elements that can be applied by the annotation type.
@Target({ ElementType.TYPE, ElementType.METHOD})
☆Set persistence Retention
The RetentionPolicy (detailed learning through API) Enumeration class defines three types of annotation persistence, which determine the method in which the Java compiler processes annotations.
@Retention(RetentionPolicy.SOURCE)
☆Add a public document named ented
By default, annotations will be ignored when you use javadoc to automatically generate documents. If you want to include annotations in the document, you must use the annotation as the document annotation.
@Documented
☆Set inheritance Inherited
By default, the annotation of the parent class does not inherit from the quilt class. To inherit, you must add the Inherited annotation.
@Inherited
Package annotation; import java. lang. annotation. documented; import java. lang. annotation. elementType; import java. lang. annotation. inherited; import java. lang. annotation. retention; import java. lang. annotation. retentionPolicy; import java. lang. annotation. target; @ Inherited @ incluented @ Retention (RetentionPolicy. RUNTIME) @ Target ({ElementType. METHOD, ElementType. TYPE}) public @ interface MyAnno {public String schoolName () default Haha University ;}
6. How to read annotations
To read the annotation content, you need to use the reflection technology. Note: To obtain comments using reflection, you must use @ Retention (RetentionPolicy. RUNTIME) for annotations.
Import java. lang. reflect. *; public class TestMyAnno {public static void main (String [] args) throws Exception {Class c = Class. forName ("anno. userModel); boolean flag = c. isAnnotationPresent (MyAnno. class); System. out. println (flag); if (flag) {MyAnno ma = (MyAnno) c. getAnnotation (MyAnno. class); System. out. println (school name: = + ma. schoolName (); // after obtaining the data, you can start processing the data }}}
Class Loader
Multiple class loaders can be installed in the Java Virtual Machine. By default, the system has three main class loaders. Each class is responsible for loading classes at specific locations: BootStrap, ExtClassLoader, and AppClassLoader.
The class loader is also a Java class, because the other class loaders of the java class are also loaded by the class loaders. Obviously, the First Class Loader must be not a java class, which is exactly the BootStrap
All class loaders in the Java Virtual Machine are organized in a tree structure with parent-child relationship. when instantiating each class loader object, you need to specify a parent class loader object for it or use the system class loader as its parent class by default.
Load.
I. parent-child relationship and jurisdiction dimensions between class loaders
Ii. Delegation mechanism of the Class Loader (understanding the ClassLoader class through API)
When the Java Virtual Machine loads a class, which class loader is dispatched to load the class?
First, the class loader of the current thread loads the first class in the thread. If Class A references Class B, the Java virtual machine uses the class loader of Class A to load Class B.
You can also directly call the ClassLoader. loadClass () method to specify a class loader to load a class.
When each class loader loads a class, it first delegates it to its parent class loader. When all the ancestor class loaders are not loaded to the class, return to the initiator class loader and cannot be loaded, the ClassNotFoundException is thrown, instead of the initiator class
The son of the loader, because there is no getChild method, even if there is one, then there are multiple sons, which one is to find?
Explain the reason why ExtClassLoader is running after the ClassLoaderTest is output to the itcast. jar package in the jre/lib/ext directory.
Package loader; import org. junit. test; public class Demo {@ Test // view the Class Loader public void testLoader0 () throws Exception {Class c = class. forName (loader. person); ClassLoader loader = c. getClassLoader (); // AppClassLoader -- policystem. out. println (loader); loader = loader. getParent (); // ExtClassLoader -- policystem. out. println (loader); loader = loader. getParent (); // null BootStrap -- CSystem. out. println (loader) ;}@ Test // Class loader public void testLoader1 () throws Exception {// AppClassLoader can only load Class c = Class in the project. forName (loader. person); Object obj = c. newInstance (); System. out. println (obj: + obj); Class c2 = Class. forName (d:/ex/UserModel. class); // This is a class outside the project, so the error Object obj2 = c2.newInstance (); System. out. println (obj2: + obj2) ;}@ Testpublic void testLoader2 () throws Exception {Hello h = new Hello (); System. out. println (h); System. out. println (h. getClass (). getClassLoader ());}}
Exercise 1. Make your own class loader
The core of the virtual machine is to load the. class file through the class loader, and then perform corresponding parsing and execution. Then we can manually load the required. class for parsing and execution to expand the functions of the virtual machine.
The following content is taken from the API documentation: the application must implement the ClassLoader subclass to expand the Java Virtual Machine to dynamically load classes.
Network class loaders must define methods findClass and loadClassData to load classes from the network. After downloading the bytes that comprise the class, it should use the defineClass method to create the class instance.
MyClassLoader. java
package loader.myClassLoader;import java.io.ByteArrayOutputStream;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;public class MyClassLoader extends ClassLoader{public Class findClass(String name) { byte[] b=null;try {b = loadClassData(name);} catch (IOException e) {e.printStackTrace();} return defineClass(null, b, 0, b.length); }private byte[] loadClassData(String fileName) throws IOException {InputStream in = new FileInputStream(fileName);byte[] b = new byte[1024];ByteArrayOutputStream out = new ByteArrayOutputStream();int len=0;while((len=in.read(b))!=-1){out.write(b,0,len);}out.close();b = out.toByteArray();return b;}}
TestMyClassLoader. java
Package loader. myClassLoader; import java. lang. reflect. method; import loader. hello; import org. junit. test; public class TestMyClassLoader {/** demonstrates using our own class loader to load classes outside the project, we can also see that the loader of this Class is our own */@ Testpublic void testLoader () throws Exception {MyClassLoader loader = new MyClassLoader (); Class clazz = loader. findClass (d:/ex/Hello. class); // Class clazz = loader. findClass (d:/ex/UserModel. class); Object obj = clazz. NewInstance (); System. out. println (obj); System. out. println (obj. getClass (). getClassLoader (); // loader. myClassLoader. myClassLoader} // loader. myClassLoader. myClassLoader @ 48f0c0d3 @ Testpublic void testLoader2 () throws Exception {MyClassLoader loader = new MyClassLoader (); Class clazz = loader. findClass (E: \ MyEclipse 10 \ paragraph2 \ bin \ loader \ Hello. class); Object obj = clazz. newInstance (); System. out. println (o Bj); // System. out. println (obj. getClass (). getClassLoader (); Method m = clazz. getMethod (call, null); m. invoke (obj, null); System. out. println (-------); Hello h = new Hello (); System. out. println (h); h. call (); // since the two objects above are the same, can they be converted to each other? ※※No, because the space is different. Hello h2 = (Hello) obj; System. out. println (h2 );}}
Running result:
2. Create your own test tool MyJUnit
(Examples of joint use of annotation and reflection)
Note: 1) JUnit uses the @ Test annotation. We use the @ MyTest annotation.
2) JUnit has been embedded into MyEclipse. As long as MyJUnit can be run independently (not embedded ), at the same time, it is not convenient for us to receive the class name and Method Name of the tested class in the form of parameters in MyJUnit. We can only enter
Receiving Method.
3) JUnit can specify a single method to call and execute, because it cannot use MyEclipse to pass Parameters, therefore, we traverse all the methods in the MyJUnit program and determine whether to call and execute the method by determining whether to declare the @ MyTest annotation.
MyTest. java
package loader.myJunit;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface MyTest {}
MyTestDemo. java
package loader.myJunit;public class MyTestDemo {public void aa(){System.out.println(AAA);}@MyTestpublic void bb(){System.out.println(BBB);}@MyTestpublic void cc(){System.out.println(CCC);}}
MyJUnit. java
Package loader. myJunit; import java. lang. reflect. method; import java. util. handler; import loader. myClassLoader. myClassLoader; public class MyJUnit {public static void main (String [] args) throws Exception {System. out. println (enter the class to be tested :); then SC = new then (System. in); String className = SC. nextLine (); // Class clazz = Class. forName (className); // must be the complete Class Name (with the package name) // Object obj = clazz. newInstance (); MyClassLoader loader = new MyClassLoader (); Class clazz = loader. findClass (className); Object obj = clazz. newInstance (); Method MS [] = clazz. getDeclaredMethods (); for (Method m: MS) {boolean boo = m. isAnnotationPresent (MyTest. class); if (boo) {m. invoke (obj, null );}}}}
Running result: