先康康这个视频。
获取一系列信息
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"); } }
|