先康康这个视频 。
获取一系列信息 domain/Person.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package domain;public class Person { private String name; private int age; public String a; public Person () { } public Person (String name, int age) { this .name = name; this .age = age; } public void eat () { System.out.println("eating" ); } public void eat (String food) { System.out.println("eating " + food); } @Override public String toString () { return "Person{" + "name='" + name + '\'' + ", age=" + age + ", a='" + a + '\'' + '}' ; } }
reflect/ReflectDemo.java
反射应用:从配置文件里执行任意类的任意方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package reflect;import java.io.InputStream;import java.lang.reflect.Constructor;import java.lang.reflect.Method;import java.util.Properties;public class ReflectDemo { public static void main (String[] args) throws Exception { Properties pro = new Properties(); ClassLoader classLoader = ReflectDemo.class .getClassLoader () ; InputStream is = classLoader.getResourceAsStream("pro.properties" ); pro.load(is); String className = pro.getProperty("className" ); String methodName = pro.getProperty("methodName" ); Class cls = Class.forName(className); Constructor cons = cls.getConstructor(); Object obj = cons.newInstance(); Method mtd = cls.getMethod(methodName); mtd.invoke(obj); } }
reflect/ReflectDemo1.java
获得class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package reflect;import domain.Person;import domain.Student;public class ReflectDemo1 { public static void main (String[] args) throws Exception { Class cls1 = Class.forName("domain.Person" ); System.out.println(cls1); Class cls2 = Person.class ; System.out.println(cls2); var p = new Person(); Class cls3 = p.getClass(); System.out.println(cls3); System.out.println(cls1 == cls2); System.out.println(cls1 == cls3); var s = new Student(); Class cls4 = s.getClass(); System.out.println(cls4); } }
reflect/ReflectDemo2.java
获得field。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package reflect;import domain.Person;import java.lang.reflect.*;public class ReflectDemo2 { public static void main (String[] args) throws Exception { Class personClass = Person.class ; Field[] fields = personClass.getFields(); for (Field field : fields) { System.out.println(field); } Field a = personClass.getField("a" ); Person p = new Person(); Object value = a.get(p); System.out.println(value); a.set(p, "zhangsan" ); System.out.println(p.a); Field name = personClass.getDeclaredField("name" ); name.setAccessible(true ); Object v2 = name.get(p); System.out.println(v2); } }
reflect/ReflectDemo3.java
获得constructor。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package reflect;import domain.Person;import java.lang.reflect.*;public class ReflectDemo3 { public static void main (String[] args) throws Exception { Class personClass = Person.class ; Constructor cons = personClass.getConstructor(String.class , int .class ) ; Object obj = cons.newInstance("zhangsan" , 15 ); System.out.println(obj); } }
工厂类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 package com.poorpool.demo;import java.lang.reflect.InvocationTargetException;interface IBook { public void read () ; } class MathBook implements IBook { @Override public void read () { System.out.println("阅读数学书" ); } } class ProgramBook implements IBook { @Override public void read () { System.out.println("阅读编程书" ); } } class Factory { private Factory () {} public static IBook getBook (String name) { try { Object obj = Class.forName(name).getDeclaredConstructor().newInstance(); if (obj instanceof IBook) return (IBook)obj; } catch (Exception e) { e.printStackTrace(); } return null ; } } public class HelloDemo { public static void main (String[] args) throws Exception { IBook qwq = Factory.getBook("com.poorpool.demo.MathBook" ); IBook pwp = Factory.getBook("com.poorpool.demo.ProgramBook" ); qwq.read(); pwp.read(); } }
多线程和单例设计模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package com.poorpool.demo;class Book { private static volatile Book instance = null ; private Book () { System.out.println(Thread.currentThread().getName() + " 实例化对象" ); } public static Book getInstance () { if (instance==null ) { synchronized (Book.class ) { if (instance==null ) { instance = new Book(); } } } return instance; } } public class HelloDemo { public static void main (String[] args) throws Exception { for (int i=0 ; i<10 ; i++) { new Thread(()->{ Book book = Book.getInstance(); System.out.println(book); }, "线程" +i).start(); } } }
reflect/ReflectDemo4.java
获得method。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package reflect;import domain.Person;import java.lang.reflect.*;public class ReflectDemo4 { public static void main (String[] args) throws Exception { Class personClass = Person.class ; Method met = personClass.getMethod("eat" , String.class ) ; Person p = new Person(); met.invoke(p, "apple" ); } }
ClassLoader 类加载器。 有三个:Bootstrap、PlatformClassLoader(以前叫ExtClassLoader)、AppClassLoader。分别为JVM系统提供的、平台类的、应用程序类的加载器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package com.poorpool.demo;class Book {}public class HelloDemo { public static void main (String[] args) throws Exception { Class<?> book = Book.class ; Class<?> string = String.class ; System.out.println(book.getClassLoader()); System.out.println(book.getClassLoader().getParent()); System.out.println(book.getClassLoader().getParent().getParent()); System.out.println(); System.out.println(string.getClassLoader()); } }
1 2 3 4 5 jdk.internal.loader.ClassLoaders$AppClassLoader@42a57993 jdk.internal.loader.ClassLoaders$PlatformClassLoader@5b2133b1 null null
null就是Bootstrap。
自定义类加载器 先编一个Message.class
丢到合适的地方。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 package com.poorpool.demo;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;class FileClassLoader extends ClassLoader { private static String CLASS_PATH = "Message.class" ; public Class<?> loadData(String className) throws Exception { byte [] re = this .loadFileClassData(); if (re!=null ) return super .defineClass(className, re, 0 , re.length); return null ; } private byte [] loadFileClassData() throws Exception { InputStream ins = new FileInputStream(new File(CLASS_PATH)); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ins.transferTo(bos); byte [] re = bos.toByteArray(); ins.close(); bos.close(); return re; } } public class HelloDemo { public static void main (String[] args) throws Exception { FileClassLoader fcl = new FileClassLoader(); Class<?> clazz = fcl.loadData("com.poorpool.demo.Message" ); Object qwq = clazz.getConstructor().newInstance(); System.out.println(qwq); System.out.println(fcl); System.out.println(fcl.getParent()); System.out.println(fcl.getParent().getParent()); System.out.println(fcl.getParent().getParent().getParent()); } }
1 2 3 4 5 com.poorpool.demo.Message@19469ea2 com.poorpool.demo.FileClassLoader@72ea2f77 jdk.internal.loader.ClassLoaders$AppClassLoader@42a57993 jdk.internal.loader.ClassLoaders$PlatformClassLoader@13221655 null
动态代理 推荐一下java3y的文章,讲得很棒。转载的一个链接 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 package com.poorpool.demo;import java.lang.reflect.Proxy;interface IProgrammer { public void coding () ; } class Poorpool implements IProgrammer { @Override public void coding () { System.out.println("写奥利给代码" ); } } public class HelloDemo { public static void main (String[] args1) throws Exception { Poorpool ppl = new Poorpool(); IProgrammer prog = (IProgrammer)Proxy.newProxyInstance(ppl.getClass().getClassLoader(), ppl.getClass().getInterfaces(), (proxy, method, args) -> { if (method.getName().equals("coding" )) { method.invoke(ppl, args); System.out.println("代理完毕" ); } else { method.invoke(ppl, args); } return null ; }); prog.coding(); } }
使用CGLIB可以避免上面使用接口的情况,避免了代理设计模式和接口的强制耦合。
自定义Annotation 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package com.poorpool.demo;import java.lang.annotation.Annotation;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;@Retention (RetentionPolicy.RUNTIME)@interface Action { public String title () default "poorpool qwq" ; public String value () ; } @Action ("pvp" )class Message { public void send (String msg) { System.out.println(msg); } } public class HelloDemo { public static void main (String[] args1) throws Exception { Class<?> clazz = Message.class ; Annotation[] annos = clazz.getAnnotations(); for (var anno : annos) System.out.println(anno); } }
自定义Annotation和工厂类结合,取消Message和Factory任何直接耦合。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 package com.poorpool.demo;import java.lang.annotation.*;import java.lang.reflect.InvocationTargetException;@Target ({ElementType.TYPE})@Retention (RetentionPolicy.RUNTIME)@interface Action{ public String value () ; } @Target ({ElementType.CONSTRUCTOR})@Retention (RetentionPolicy.RUNTIME)@interface Instance{ public String value () ; } interface IChannel extends AutoCloseable { public boolean build () ; } class InternetChannel implements IChannel { @Override public boolean build () { System.out.println("建立互联网信道" ); return true ; } @Override public void close () throws Exception { System.out.println("关闭互联网信道" ); } } class RadioChannel implements IChannel { @Override public boolean build () { System.out.println("建立无线电信道" ); return true ; } @Override public void close () throws Exception { System.out.println("关闭无线电信道" ); } } class Factory { private Factory () {} public static <T> T getInstance (String className) { try { return (T) Class.forName(className).getDeclaredConstructor().newInstance(); } catch (Exception e) { e.printStackTrace(); return null ; } } } @Action ("com.poorpool.demo.RadioChannel" )class Message { private IChannel channel; @Instance ("com.poorpool.demo.Factory" ) public Message () { try { Action actAnno = super .getClass().getAnnotation(Action.class ) ; Instance ins = super .getClass().getConstructor().getAnnotation(Instance.class ) ; String facName = ins.value(); String actName = actAnno.value(); Class<?> facClazz = Class.forName(facName); this .channel = (IChannel)facClazz.getMethod("getInstance" , String.class ).invoke (null , actName ) ; } catch (Exception e) { e.printStackTrace(); } } public void echo (String qwq) throws Exception { if (this .channel.build()) System.out.println(qwq); this .channel.close(); } } public class HelloDemo { public static void main (String[] args) throws Exception { Message msg = new Message(); msg.echo("hello" ); } }