├── src ├── main │ └── java │ │ └── org │ │ └── cnt │ │ └── java │ │ ├── annotation │ │ ├── typ │ │ │ ├── f │ │ │ │ ├── F2.java │ │ │ │ ├── F1.java │ │ │ │ └── FTest.java │ │ │ ├── c │ │ │ │ ├── CR21.java │ │ │ │ ├── C2.java │ │ │ │ ├── CR22.java │ │ │ │ ├── CR31.java │ │ │ │ ├── C1.java │ │ │ │ ├── CR33.java │ │ │ │ ├── CR32.java │ │ │ │ ├── CR23.java │ │ │ │ ├── CR11.java │ │ │ │ └── CTest.java │ │ │ ├── i │ │ │ │ ├── I2.java │ │ │ │ ├── I1.java │ │ │ │ └── ITest.java │ │ │ ├── m │ │ │ │ ├── M2.java │ │ │ │ ├── M1.java │ │ │ │ └── MTest.java │ │ │ └── ci │ │ │ │ ├── CI1.java │ │ │ │ └── CITest.java │ │ └── ann │ │ │ ├── f │ │ │ ├── AnnF13.java │ │ │ └── AnnF23.java │ │ │ ├── m │ │ │ ├── AnnM13.java │ │ │ ├── AnnM23.java │ │ │ ├── AnnM33.java │ │ │ └── AnnM43.java │ │ │ ├── c │ │ │ ├── AnnC13.java │ │ │ ├── AnnC23.java │ │ │ ├── AnnC33.java │ │ │ └── AnnC43.java │ │ │ ├── a │ │ │ ├── Ann01.java │ │ │ ├── Ann02.java │ │ │ └── ATest.java │ │ │ ├── i │ │ │ ├── AnnI13.java │ │ │ ├── AnnI23.java │ │ │ ├── AnnI33.java │ │ │ └── AnnI43.java │ │ │ └── r │ │ │ ├── AnnRC11.java │ │ │ ├── AnnRC12.java │ │ │ ├── AnnR11.java │ │ │ └── AnnR12.java │ │ ├── reflect │ │ └── method │ │ │ ├── Impl2.java │ │ │ ├── Parent2.java │ │ │ ├── Parent3.java │ │ │ ├── Child3.java │ │ │ ├── Child2.java │ │ │ ├── Parent.java │ │ │ ├── Inter.java │ │ │ ├── Impl.java │ │ │ ├── Child.java │ │ │ └── MainTest.java │ │ ├── jdkproxy │ │ ├── InterA.java │ │ ├── InterB.java │ │ ├── ClassAB.java │ │ ├── ActualHandler.java │ │ └── JpMain.java │ │ ├── generic │ │ ├── ProblemForTypeErase.java │ │ ├── TypeFixup.java │ │ ├── Generic1.java │ │ ├── TypeErase.java │ │ ├── CheckedList.java │ │ ├── TypeBound.java │ │ ├── UnboundTypeParam.java │ │ ├── Generic.java │ │ ├── TypeParam.java │ │ ├── ArrayCvCtv.java │ │ └── ListCvCtv.java │ │ ├── designpattern │ │ └── visitor │ │ │ ├── v2 │ │ │ ├── Element.java │ │ │ ├── Visitor.java │ │ │ ├── VisitorB.java │ │ │ ├── ElementA.java │ │ │ ├── ElementB.java │ │ │ ├── VisitorA.java │ │ │ └── ObjectStructure.java │ │ │ └── v1 │ │ │ ├── GreatWall.java │ │ │ ├── PalaceMuseum.java │ │ │ ├── SummerPalace.java │ │ │ ├── Guest.java │ │ │ └── Host.java │ │ ├── utils │ │ ├── Sleeper.java │ │ ├── Randomer.java │ │ ├── Log.java │ │ ├── Logger.java │ │ ├── Methods.java │ │ └── Byter.java │ │ ├── classloader │ │ ├── B.java │ │ ├── A.java │ │ └── ClazzLoader.java │ │ ├── thread │ │ ├── rwlock │ │ │ └── RDLock.java │ │ ├── coop │ │ │ ├── ThreadCo3.java │ │ │ ├── ThreadCo1.java │ │ │ ├── ThreadCo2.java │ │ │ └── ThreadCo4.java │ │ ├── prco │ │ │ └── ProdCons.java │ │ ├── obj │ │ │ └── Obj.java │ │ ├── sync │ │ │ └── Synchronized.java │ │ ├── thre │ │ │ └── Thre.java │ │ └── basic │ │ │ └── ThreadOp.java │ │ ├── io │ │ ├── bio │ │ │ ├── Client.java │ │ │ └── BioServer.java │ │ ├── aio │ │ │ └── AioServer.java │ │ └── nio │ │ │ └── NioServer.java │ │ ├── filechannel │ │ └── FcMain.java │ │ └── digit │ │ └── Digit.java └── test │ └── java │ └── org │ └── cnt │ └── java │ └── code │ └── AppTest.java ├── .gitignore ├── pom.xml └── LICENSE /src/main/java/org/cnt/java/annotation/typ/f/F2.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.f; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-07-26 6 | */ 7 | public class F2 extends F1 { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/c/CR21.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.c; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-07-25 6 | */ 7 | public class CR21 extends CR11 { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/reflect/method/Impl2.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.reflect.method; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-09-20 6 | */ 7 | public class Impl2 extends Impl { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/jdkproxy/InterA.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.jdkproxy; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2020-07-03 6 | */ 7 | public interface InterA { 8 | 9 | void methodA1(); 10 | 11 | void methodA2(); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/jdkproxy/InterB.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.jdkproxy; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2020-07-03 6 | */ 7 | public interface InterB { 8 | 9 | void methodB1(); 10 | 11 | void methodB2(); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/generic/ProblemForTypeErase.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.generic; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2018-07-09 6 | */ 7 | public class ProblemForTypeErase { 8 | 9 | //new 10 | //instenceof 11 | //new T[] 12 | //new A[] 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/generic/TypeFixup.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.generic; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2018-07-09 6 | */ 7 | public class TypeFixup { 8 | 9 | //泛型数组 10 | 11 | public static void main(String[] args) { 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/designpattern/visitor/v2/Element.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.designpattern.visitor.v2; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-07-21 6 | */ 7 | public interface Element { 8 | 9 | //接受访问者 10 | void accept(V visitor); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/designpattern/visitor/v2/Visitor.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.designpattern.visitor.v2; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-07-21 6 | */ 7 | public interface Visitor { 8 | 9 | //访问元素 10 | void visit(E element); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/designpattern/visitor/v1/GreatWall.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.designpattern.visitor.v1; 2 | 3 | /** 4 | *

长城,景点 5 | * @author lixinjie 6 | * @since 2019-07-21 7 | */ 8 | public interface GreatWall { 9 | 10 | //让访客看 11 | void accept(Guest guest); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/reflect/method/Parent2.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.reflect.method; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-09-11 6 | */ 7 | public abstract class Parent2 { 8 | 9 | public abstract String m1(); 10 | 11 | protected abstract String m2(); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/designpattern/visitor/v1/PalaceMuseum.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.designpattern.visitor.v1; 2 | 3 | /** 4 | *

故宫,景点 5 | * @author lixinjie 6 | * @since 2019-07-21 7 | */ 8 | public interface PalaceMuseum { 9 | 10 | //让访客看 11 | void accept(Guest guest); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/designpattern/visitor/v1/SummerPalace.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.designpattern.visitor.v1; 2 | 3 | /** 4 | *

颐和园,景点 5 | * @author lixinjie 6 | * @since 2019-07-21 7 | */ 8 | public interface SummerPalace { 9 | 10 | //让访客看 11 | void accept(Guest guest); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/designpattern/visitor/v2/VisitorB.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.designpattern.visitor.v2; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-07-21 6 | */ 7 | public interface VisitorB extends Visitor { 8 | 9 | @Override 10 | void visit(ElementB element); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/designpattern/visitor/v2/ElementA.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.designpattern.visitor.v2; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-07-21 6 | */ 7 | public interface ElementA extends Element { 8 | 9 | @Override 10 | void accept(VisitorA visitor); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/designpattern/visitor/v2/ElementB.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.designpattern.visitor.v2; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-07-21 6 | */ 7 | public interface ElementB extends Element { 8 | 9 | @Override 10 | void accept(VisitorB visitor); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/designpattern/visitor/v2/VisitorA.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.designpattern.visitor.v2; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-07-21 6 | */ 7 | public interface VisitorA extends Visitor { 8 | 9 | @Override 10 | void visit(ElementA element); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/reflect/method/Parent3.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.reflect.method; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-09-11 6 | */ 7 | public class Parent3 { 8 | 9 | public String f1 = "Parent3.f1"; 10 | 11 | protected String f2 = "Parent3.f2"; 12 | 13 | private String f3 = "Parent3.f3"; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/reflect/method/Child3.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.reflect.method; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-09-11 6 | */ 7 | public class Child3 extends Parent3 { 8 | 9 | public String f1 = "Child3.f1"; 10 | 11 | protected String f2 = "Child3.f2"; 12 | 13 | private String f3 = "Child3.f3"; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/i/I2.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.i; 2 | 3 | import org.cnt.java.annotation.ann.i.AnnI23; 4 | import org.cnt.java.annotation.ann.i.AnnI43; 5 | 6 | /** 7 | * @author lixinjie 8 | * @since 2019-07-25 9 | */ 10 | @AnnI23 11 | @AnnI43("I2") 12 | public interface I2 extends I1 { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/utils/Sleeper.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.utils; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-07-08 6 | */ 7 | public class Sleeper { 8 | 9 | public static void sleep(int second) { 10 | try { 11 | Thread.sleep(second * 1000); 12 | } catch (InterruptedException e) { 13 | 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/c/C2.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.c; 2 | 3 | import org.cnt.java.annotation.ann.c.AnnC23; 4 | import org.cnt.java.annotation.ann.c.AnnC43; 5 | 6 | /** 7 | * @author lixinjie 8 | * @since 2019-07-25 9 | */ 10 | @AnnC23 11 | @AnnC43(id = "C2.C43") 12 | public class C2 extends C1 { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/c/CR22.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.c; 2 | 3 | import org.cnt.java.annotation.ann.r.AnnR11; 4 | import org.cnt.java.annotation.ann.r.AnnRC12; 5 | 6 | /** 7 | * @author lixinjie 8 | * @since 2019-07-25 9 | */ 10 | @AnnR11(id = "C2.R11.1") 11 | @AnnRC12({}) 12 | public class CR22 extends CR11 { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/designpattern/visitor/v2/ObjectStructure.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.designpattern.visitor.v2; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @author lixinjie 7 | * @since 2019-07-21 8 | */ 9 | public interface ObjectStructure { 10 | 11 | //所有元素 12 | List getElements(); 13 | 14 | //所有访问者 15 | List getVisitors(); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/classloader/B.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.classloader; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-07-23 6 | */ 7 | public class B { 8 | 9 | public static final int b = getA(); 10 | 11 | static { 12 | System.out.println("-B-"); 13 | } 14 | 15 | static int getA() { 16 | System.out.println("-b-"); 17 | return 2; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/reflect/method/Child2.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.reflect.method; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-09-11 6 | */ 7 | public class Child2 extends Parent2 { 8 | 9 | @Override 10 | public String m1() { 11 | return "Child2.m1"; 12 | } 13 | 14 | @Override 15 | protected String m2() { 16 | return "Child2.m2"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/c/CR31.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.c; 2 | 3 | import org.cnt.java.annotation.ann.r.AnnR11; 4 | import org.cnt.java.annotation.ann.r.AnnR12; 5 | 6 | /** 7 | * @author lixinjie 8 | * @since 2019-07-25 9 | */ 10 | @AnnR11(id = "C1.R11.1") 11 | @AnnR12(id = "C1.R12.1") 12 | @AnnR12(id = "C1.R12.2") 13 | public class CR31 { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/classloader/A.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.classloader; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-07-23 6 | */ 7 | public class A extends B { 8 | 9 | public static final int a = getA(); 10 | 11 | static { 12 | System.out.println("-A-"); 13 | } 14 | 15 | static int getA() { 16 | System.out.println("-a-"); 17 | return 1; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/m/M2.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.m; 2 | 3 | import org.cnt.java.annotation.ann.m.AnnM23; 4 | import org.cnt.java.annotation.ann.m.AnnM43; 5 | 6 | /** 7 | * @author lixinjie 8 | * @since 2019-07-26 9 | */ 10 | public class M2 extends M1 { 11 | 12 | @AnnM23 13 | @AnnM43("M2") 14 | @Override 15 | public void m1() { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/c/C1.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.c; 2 | 3 | import org.cnt.java.annotation.ann.c.AnnC13; 4 | import org.cnt.java.annotation.ann.c.AnnC33; 5 | import org.cnt.java.annotation.ann.c.AnnC43; 6 | 7 | /** 8 | * @author lixinjie 9 | * @since 2019-07-25 10 | */ 11 | @AnnC13 12 | @AnnC33 13 | @AnnC43(id = "C1.C43") 14 | public class C1 { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/c/CR33.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.c; 2 | 3 | import org.cnt.java.annotation.ann.r.AnnR11; 4 | import org.cnt.java.annotation.ann.r.AnnR12; 5 | 6 | /** 7 | * @author lixinjie 8 | * @since 2019-07-25 9 | */ 10 | @AnnR11(id = "C3.R11.1") 11 | @AnnR11(id = "C3.R11.2") 12 | @AnnR12(id = "C3.R12.1") 13 | public class CR33 extends CR31 { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/reflect/method/Parent.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.reflect.method; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-09-11 6 | */ 7 | public class Parent { 8 | 9 | public String m1() { 10 | return "Parent.m1"; 11 | } 12 | 13 | protected String m2() { 14 | return "Parent.m2"; 15 | } 16 | 17 | private String m3() { 18 | return "Parent.m3"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/f/F1.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.f; 2 | 3 | import org.cnt.java.annotation.ann.f.AnnF13; 4 | import org.cnt.java.annotation.ann.f.AnnF23; 5 | 6 | /** 7 | * @author lixinjie 8 | * @since 2019-07-26 9 | */ 10 | public class F1 { 11 | 12 | @AnnF13 13 | @AnnF23 14 | public String f1; 15 | 16 | @AnnF13 17 | @AnnF23 18 | public String f2; 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/designpattern/visitor/v1/Guest.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.designpattern.visitor.v1; 2 | 3 | /** 4 | *

客人,访问者 5 | * @author lixinjie 6 | * @since 2019-07-21 7 | */ 8 | public interface Guest { 9 | 10 | //看故宫 11 | void look(PalaceMuseum PalaceMuseum); 12 | 13 | //看长城 14 | void look(GreatWall GreatWall); 15 | 16 | //看颐和园 17 | void look(SummerPalace SummerPalace); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/utils/Randomer.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.utils; 2 | 3 | import java.util.Random; 4 | 5 | /** 6 | * @author lixinjie 7 | * @since 2019-07-09 8 | */ 9 | public class Randomer { 10 | 11 | public static int random(int max) { 12 | return random(0, max); 13 | } 14 | 15 | public static int random(int min, int max) { 16 | return min + new Random().nextInt(max - min + 1); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/reflect/method/Inter.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.reflect.method; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-09-19 6 | */ 7 | public interface Inter { 8 | 9 | String m1(); 10 | 11 | default String m2() { 12 | return "Inter.m2"; 13 | } 14 | 15 | default String m3() { 16 | return "Inter.m3"; 17 | } 18 | 19 | static String m4() { 20 | return "Inter.m4"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/c/CR32.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.c; 2 | 3 | import org.cnt.java.annotation.ann.r.AnnR11; 4 | import org.cnt.java.annotation.ann.r.AnnR12; 5 | import org.cnt.java.annotation.ann.r.AnnRC12; 6 | 7 | /** 8 | * @author lixinjie 9 | * @since 2019-07-25 10 | */ 11 | @AnnR11(id = "C2.R11.1") 12 | @AnnRC12({@AnnR12(id = "C2.R12.1")}) 13 | public class CR32 extends CR31 { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/utils/Log.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.utils; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-09-20 6 | */ 7 | public class Log { 8 | 9 | public static void log(Object o) { 10 | System.out.println(o); 11 | } 12 | 13 | public static void log(String str, Object... os) { 14 | for (Object o : os) { 15 | str = str.replaceFirst("\\{\\}", String.valueOf(o)); 16 | } 17 | log(str); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/reflect/method/Impl.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.reflect.method; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-09-19 6 | */ 7 | public class Impl implements Inter { 8 | 9 | @Override 10 | public String m1() { 11 | return "Impl.m1"; 12 | } 13 | 14 | @Override 15 | public String m2() { 16 | return "Impl.m2"; 17 | } 18 | 19 | public static String m5() { 20 | return "Impl.m5"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/reflect/method/Child.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.reflect.method; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-09-11 6 | */ 7 | public class Child extends Parent { 8 | 9 | @Override 10 | public String m1() { 11 | return "Child.m1"; 12 | } 13 | 14 | @Override 15 | protected String m2() { 16 | return "Child.m2"; 17 | } 18 | 19 | private String m3() { 20 | return "Child.m3"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/designpattern/visitor/v1/Host.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.designpattern.visitor.v1; 2 | 3 | /** 4 | *

东道主,协调者 5 | * @author lixinjie 6 | * @since 2019-07-21 7 | */ 8 | public interface Host { 9 | 10 | //带朋友去故宫 11 | void show(PalaceMuseum PalaceMuseum, Guest guest); 12 | 13 | //带朋友去长城 14 | void show(GreatWall GreatWall, Guest guest); 15 | 16 | //带朋友去颐和园 17 | void show(SummerPalace SummerPalace, Guest guest); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/c/CR23.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.c; 2 | 3 | import org.cnt.java.annotation.ann.r.AnnR11; 4 | import org.cnt.java.annotation.ann.r.AnnR12; 5 | import org.cnt.java.annotation.ann.r.AnnRC12; 6 | 7 | /** 8 | * @author lixinjie 9 | * @since 2019-07-25 10 | */ 11 | @AnnR11(id = "C3.R11.1") 12 | @AnnR11(id = "C3.R11.2") 13 | @AnnRC12({@AnnR12(id = "C3.R12.1")}) 14 | public class CR23 extends CR11 { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/m/M1.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.m; 2 | 3 | import org.cnt.java.annotation.ann.m.AnnM13; 4 | import org.cnt.java.annotation.ann.m.AnnM33; 5 | import org.cnt.java.annotation.ann.m.AnnM43; 6 | 7 | /** 8 | * @author lixinjie 9 | * @since 2019-07-26 10 | */ 11 | public class M1 { 12 | 13 | @AnnM13 14 | @AnnM33 15 | @AnnM43("M1") 16 | public void m1() {} 17 | 18 | @AnnM13 19 | @AnnM33 20 | @AnnM43("M1") 21 | public void m2() {} 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/f/AnnF13.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.f; 2 | 3 | import static java.lang.annotation.ElementType.FIELD; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * @author lixinjie 12 | * @since 2019-07-25 13 | */ 14 | @Documented 15 | @Retention(RUNTIME) 16 | @Target(FIELD) 17 | public @interface AnnF13 { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/f/AnnF23.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.f; 2 | 3 | import static java.lang.annotation.ElementType.FIELD; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * @author lixinjie 12 | * @since 2019-07-25 13 | */ 14 | @Documented 15 | @Retention(RUNTIME) 16 | @Target(FIELD) 17 | public @interface AnnF23 { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/m/AnnM13.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.m; 2 | 3 | import static java.lang.annotation.ElementType.METHOD; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * @author lixinjie 12 | * @since 2019-07-25 13 | */ 14 | @Documented 15 | @Retention(RUNTIME) 16 | @Target(METHOD) 17 | public @interface AnnM13 { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/m/AnnM23.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.m; 2 | 3 | import static java.lang.annotation.ElementType.METHOD; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * @author lixinjie 12 | * @since 2019-07-25 13 | */ 14 | @Documented 15 | @Retention(RUNTIME) 16 | @Target(METHOD) 17 | public @interface AnnM23 { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/ci/CI1.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.ci; 2 | 3 | import org.cnt.java.annotation.ann.m.AnnM23; 4 | import org.cnt.java.annotation.ann.m.AnnM43; 5 | import org.cnt.java.annotation.typ.i.I1; 6 | 7 | /** 8 | * @author lixinjie 9 | * @since 2019-07-25 10 | */ 11 | public class CI1 implements I1 { 12 | 13 | String f1; 14 | 15 | @AnnM23 16 | @AnnM43("CI1") 17 | @Override 18 | public void m1() { 19 | } 20 | 21 | @Override 22 | public void m2() { 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/c/AnnC13.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.c; 2 | 3 | import static java.lang.annotation.ElementType.TYPE; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * @author lixinjie 12 | * @since 2019-07-25 13 | */ 14 | @Documented 15 | @Retention(RUNTIME) 16 | @Target(TYPE) 17 | public @interface AnnC13 { 18 | 19 | String id() default ""; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/c/AnnC23.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.c; 2 | 3 | import static java.lang.annotation.ElementType.TYPE; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * @author lixinjie 12 | * @since 2019-07-25 13 | */ 14 | @Documented 15 | @Retention(RUNTIME) 16 | @Target(TYPE) 17 | public @interface AnnC23 { 18 | 19 | String id() default ""; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/a/Ann01.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.a; 2 | 3 | import static java.lang.annotation.ElementType.TYPE; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.Target; 9 | 10 | @Documented 11 | @Retention(RUNTIME) 12 | @Target(TYPE) 13 | /** 14 | * @author lixinjie 15 | * @since 2019-07-25 16 | */ 17 | public @interface Ann01 { 18 | 19 | String id() default "Ann01"; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/a/Ann02.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.a; 2 | 3 | import static java.lang.annotation.ElementType.TYPE; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.Target; 9 | 10 | @Documented 11 | @Retention(RUNTIME) 12 | @Target(TYPE) 13 | /** 14 | * @author lixinjie 15 | * @since 2019-07-25 16 | */ 17 | public @interface Ann02 { 18 | 19 | String id() default "Ann02"; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/i/AnnI13.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.i; 2 | 3 | import static java.lang.annotation.ElementType.TYPE; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * @author lixinjie 12 | * @since 2019-07-25 13 | */ 14 | @Documented 15 | @Retention(RUNTIME) 16 | @Target(TYPE) 17 | public @interface AnnI13 { 18 | 19 | String value() default ""; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/i/AnnI23.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.i; 2 | 3 | import static java.lang.annotation.ElementType.TYPE; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * @author lixinjie 12 | * @since 2019-07-25 13 | */ 14 | @Documented 15 | @Retention(RUNTIME) 16 | @Target(TYPE) 17 | public @interface AnnI23 { 18 | 19 | String value() default ""; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/m/AnnM33.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.m; 2 | 3 | import static java.lang.annotation.ElementType.METHOD; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.Inherited; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.Target; 10 | 11 | /** 12 | * @author lixinjie 13 | * @since 2019-07-25 14 | */ 15 | @Documented 16 | @Retention(RUNTIME) 17 | @Target(METHOD) 18 | @Inherited 19 | public @interface AnnM33 { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/c/AnnC33.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.c; 2 | 3 | import static java.lang.annotation.ElementType.TYPE; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.Inherited; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.Target; 10 | 11 | /** 12 | * @author lixinjie 13 | * @since 2019-07-25 14 | */ 15 | @Documented 16 | @Retention(RUNTIME) 17 | @Target(TYPE) 18 | @Inherited 19 | public @interface AnnC33 { 20 | 21 | String id() default ""; 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/c/AnnC43.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.c; 2 | 3 | import static java.lang.annotation.ElementType.TYPE; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.Inherited; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.Target; 10 | 11 | /** 12 | * @author lixinjie 13 | * @since 2019-07-25 14 | */ 15 | @Documented 16 | @Retention(RUNTIME) 17 | @Target(TYPE) 18 | @Inherited 19 | public @interface AnnC43 { 20 | 21 | String id() default ""; 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/jdkproxy/ClassAB.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.jdkproxy; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2020-07-03 6 | */ 7 | public class ClassAB implements InterA, InterB { 8 | 9 | @Override 10 | public void methodB1() { 11 | System.out.println("methodB1"); 12 | } 13 | 14 | @Override 15 | public void methodB2() { 16 | System.out.println("methodB2"); 17 | } 18 | 19 | @Override 20 | public void methodA1() { 21 | System.out.println("methodA1"); 22 | } 23 | 24 | @Override 25 | public void methodA2() { 26 | System.out.println("methodA2"); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/i/AnnI33.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.i; 2 | 3 | import static java.lang.annotation.ElementType.TYPE; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.Inherited; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.Target; 10 | 11 | /** 12 | * @author lixinjie 13 | * @since 2019-07-25 14 | */ 15 | @Documented 16 | @Retention(RUNTIME) 17 | @Target(TYPE) 18 | @Inherited 19 | public @interface AnnI33 { 20 | 21 | String value() default ""; 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/i/AnnI43.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.i; 2 | 3 | import static java.lang.annotation.ElementType.TYPE; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.Inherited; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.Target; 10 | 11 | /** 12 | * @author lixinjie 13 | * @since 2019-07-25 14 | */ 15 | @Documented 16 | @Retention(RUNTIME) 17 | @Target(TYPE) 18 | @Inherited 19 | public @interface AnnI43 { 20 | 21 | String value() default ""; 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/m/AnnM43.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.m; 2 | 3 | import static java.lang.annotation.ElementType.METHOD; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.Inherited; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.Target; 10 | 11 | /** 12 | * @author lixinjie 13 | * @since 2019-07-25 14 | */ 15 | @Documented 16 | @Retention(RUNTIME) 17 | @Target(METHOD) 18 | @Inherited 19 | public @interface AnnM43 { 20 | 21 | String value() default ""; 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/c/CR11.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.c; 2 | 3 | import org.cnt.java.annotation.ann.r.AnnR11; 4 | import org.cnt.java.annotation.ann.r.AnnR12; 5 | import org.cnt.java.annotation.ann.r.AnnRC12; 6 | 7 | /** 8 | * @author lixinjie 9 | * @since 2019-07-25 10 | */ 11 | @AnnR11(id = "C1.R11.1") 12 | @AnnR11(id = "C1.R11.2") 13 | @AnnR11(id = "C1.R11.3") 14 | @AnnR11(id = "C1.R11.4") 15 | @AnnR11(id = "C1.R11.5") 16 | @AnnRC12({@AnnR12(id = "C1.R12.1"), 17 | @AnnR12(id = "C1.R12.2"), 18 | @AnnR12(id = "C1.R12.3"), 19 | @AnnR12(id = "C1.R12.4"), 20 | @AnnR12(id = "C1.R12.5")}) 21 | public class CR11 { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/classloader/ClazzLoader.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.classloader; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-07-23 6 | */ 7 | public class ClazzLoader { 8 | 9 | public static void main(String[] args) { 10 | try { 11 | System.out.println(A.class); 12 | Class fa = Class.forName("org.cnt.java.classloader.A"); 13 | Class ca = A.class; 14 | System.out.println(ca == fa); 15 | Class clazz = ClazzLoader.class.getClassLoader().loadClass("org.cnt.java.classloader.A"); 16 | System.out.println(clazz); 17 | System.out.println(A.a); 18 | } catch (Exception e) { 19 | e.printStackTrace(); 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/i/I1.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.i; 2 | 3 | import org.cnt.java.annotation.ann.i.AnnI13; 4 | import org.cnt.java.annotation.ann.i.AnnI33; 5 | import org.cnt.java.annotation.ann.i.AnnI43; 6 | import org.cnt.java.annotation.ann.m.AnnM13; 7 | import org.cnt.java.annotation.ann.m.AnnM33; 8 | import org.cnt.java.annotation.ann.m.AnnM43; 9 | 10 | /** 11 | * @author lixinjie 12 | * @since 2019-07-25 13 | */ 14 | @AnnI13 15 | @AnnI33("I1") 16 | @AnnI43("I1") 17 | public interface I1 { 18 | 19 | @AnnM13 20 | @AnnM33 21 | @AnnM43("I1") 22 | void m1(); 23 | 24 | @AnnM13 25 | @AnnM33 26 | @AnnM43("I1") 27 | void m2(); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/r/AnnRC11.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.r; 2 | 3 | import static java.lang.annotation.ElementType.FIELD; 4 | import static java.lang.annotation.ElementType.METHOD; 5 | import static java.lang.annotation.ElementType.TYPE; 6 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 7 | 8 | import java.lang.annotation.Documented; 9 | import java.lang.annotation.Inherited; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.Target; 12 | 13 | /** 14 | * @author lixinjie 15 | * @since 2019-07-25 16 | */ 17 | @Documented 18 | @Retention(RUNTIME) 19 | @Target({TYPE, FIELD, METHOD}) 20 | @Inherited 21 | public @interface AnnRC11 { 22 | 23 | AnnR11[] value(); 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/r/AnnRC12.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.r; 2 | 3 | import static java.lang.annotation.ElementType.FIELD; 4 | import static java.lang.annotation.ElementType.METHOD; 5 | import static java.lang.annotation.ElementType.TYPE; 6 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 7 | 8 | import java.lang.annotation.Documented; 9 | import java.lang.annotation.Inherited; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.Target; 12 | 13 | /** 14 | * @author lixinjie 15 | * @since 2019-07-25 16 | */ 17 | @Documented 18 | @Retention(RUNTIME) 19 | @Target({TYPE, FIELD, METHOD}) 20 | @Inherited 21 | public @interface AnnRC12 { 22 | 23 | AnnR12[] value(); 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/generic/Generic1.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.generic; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2018-07-06 6 | */ 7 | public class Generic1 { 8 | 9 | public static void main(String[] args) { 10 | A a = new A<>(); 11 | a.setT("李新杰"); 12 | a.setO("lixinjie"); 13 | String name = a.getT(); 14 | String py = (String)a.getO(); 15 | System.out.println(name + py); 16 | } 17 | 18 | static class A { 19 | private T t; 20 | private Object o; 21 | 22 | public T getT() { 23 | return t; 24 | } 25 | public void setT(T t) { 26 | this.t = t; 27 | } 28 | public Object getO() { 29 | return o; 30 | } 31 | public void setO(Object o) { 32 | this.o = o; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | /target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | 5 | ### STS ### 6 | .apt_generated 7 | .classpath 8 | .factorypath 9 | .project 10 | .settings 11 | .springBeans 12 | .sts4-cache 13 | 14 | ### IntelliJ IDEA ### 15 | .idea 16 | *.iws 17 | *.iml 18 | *.ipr 19 | 20 | ### NetBeans ### 21 | /nbproject/private/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ 26 | /build/ 27 | 28 | # Compiled class file 29 | *.class 30 | 31 | # Log file 32 | *.log 33 | 34 | # BlueJ files 35 | *.ctxt 36 | 37 | # Mobile Tools for Java (J2ME) 38 | .mtj.tmp/ 39 | 40 | # Package Files # 41 | *.jar 42 | *.war 43 | *.nar 44 | *.ear 45 | *.zip 46 | *.tar.gz 47 | *.rar 48 | 49 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 50 | hs_err_pid* 51 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/r/AnnR11.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.r; 2 | 3 | import static java.lang.annotation.ElementType.FIELD; 4 | import static java.lang.annotation.ElementType.METHOD; 5 | import static java.lang.annotation.ElementType.TYPE; 6 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 7 | 8 | import java.lang.annotation.Documented; 9 | import java.lang.annotation.Inherited; 10 | import java.lang.annotation.Repeatable; 11 | import java.lang.annotation.Retention; 12 | import java.lang.annotation.Target; 13 | 14 | /** 15 | * @author lixinjie 16 | * @since 2019-07-25 17 | */ 18 | @Documented 19 | @Retention(RUNTIME) 20 | @Target({TYPE, FIELD, METHOD}) 21 | @Inherited 22 | @Repeatable(AnnRC11.class) 23 | public @interface AnnR11 { 24 | 25 | String id() default ""; 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/r/AnnR12.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.r; 2 | 3 | import static java.lang.annotation.ElementType.FIELD; 4 | import static java.lang.annotation.ElementType.METHOD; 5 | import static java.lang.annotation.ElementType.TYPE; 6 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 7 | 8 | import java.lang.annotation.Documented; 9 | import java.lang.annotation.Inherited; 10 | import java.lang.annotation.Repeatable; 11 | import java.lang.annotation.Retention; 12 | import java.lang.annotation.Target; 13 | 14 | /** 15 | * @author lixinjie 16 | * @since 2019-07-25 17 | */ 18 | @Documented 19 | @Retention(RUNTIME) 20 | @Target({TYPE, FIELD, METHOD}) 21 | @Inherited 22 | @Repeatable(AnnRC12.class) 23 | public @interface AnnR12 { 24 | 25 | String id() default ""; 26 | } 27 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | org.cnt 6 | java-code-demo 7 | 1.0.0 8 | jar 9 | 10 | java-code-demo 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 16 | 17 | 18 | 19 | junit 20 | junit 21 | 3.8.1 22 | test 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/test/java/org/cnt/java/code/AppTest.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.code; 2 | 3 | import junit.framework.Test; 4 | import junit.framework.TestCase; 5 | import junit.framework.TestSuite; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest 11 | extends TestCase 12 | { 13 | /** 14 | * Create the test case 15 | * 16 | * @param testName name of the test case 17 | */ 18 | public AppTest( String testName ) 19 | { 20 | super( testName ); 21 | } 22 | 23 | /** 24 | * @return the suite of tests being tested 25 | */ 26 | public static Test suite() 27 | { 28 | return new TestSuite( AppTest.class ); 29 | } 30 | 31 | /** 32 | * Rigourous Test :-) 33 | */ 34 | public void testApp() 35 | { 36 | assertTrue( true ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/generic/TypeErase.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.generic; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2018-07-09 6 | */ 7 | public class TypeErase { 8 | 9 | 10 | static class A { 11 | private Object obj; 12 | 13 | public Object getObj() { 14 | return obj; 15 | } 16 | public void setObj(Object obj) { 17 | this.obj = obj; 18 | } 19 | } 20 | 21 | static class B { 22 | private T obj; 23 | 24 | public T getObj() { 25 | return obj; 26 | } 27 | public void setObj(T obj) { 28 | this.obj = obj; 29 | } 30 | } 31 | 32 | public static void main(String[] args) { 33 | A a = new A(); 34 | a.setObj("李新杰"); 35 | String obj1 = (String)a.getObj(); 36 | B b = new B<>(); 37 | b.setObj("李新杰"); 38 | String obj2 = b.getObj(); 39 | System.out.println(obj1 + "," + obj2); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/ann/a/ATest.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.ann.a; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-08-05 6 | */ 7 | @Ann01 8 | @Ann02(id = "ATest.Ann02") 9 | public class ATest { 10 | 11 | public static void main(String[] args) { 12 | try { 13 | showAnn(); 14 | } catch (Exception e) { 15 | e.printStackTrace(); 16 | } 17 | } 18 | 19 | static void showAnn() throws Exception { 20 | Ann01 ann01 = ATest.class.getAnnotation(Ann01.class); 21 | System.out.println(ann01.id()); 22 | System.out.println(ann01.annotationType().getDeclaredMethod("id").getDefaultValue()); 23 | System.out.println(ann01); 24 | Ann02 ann02 = ATest.class.getAnnotation(Ann02.class); 25 | System.out.println(ann02.id()); 26 | System.out.println(ann02.annotationType().getDeclaredMethod("id").getDefaultValue()); 27 | System.out.println(ann02); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/jdkproxy/ActualHandler.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.jdkproxy; 2 | 3 | import java.lang.reflect.InvocationHandler; 4 | import java.lang.reflect.Method; 5 | 6 | /** 7 | * @author lixinjie 8 | * @since 2020-07-03 9 | */ 10 | public class ActualHandler implements InvocationHandler { 11 | 12 | private ClassAB classAB; 13 | private Object proxy; 14 | 15 | public ActualHandler(ClassAB classAB) { 16 | this.classAB = classAB; 17 | } 18 | 19 | @Override 20 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 21 | System.out.println("this.proxy == proxy : " + (this.proxy == proxy)); 22 | String name = method.getName(); 23 | System.out.println("before " + name); 24 | Object val = method.invoke(classAB, args); 25 | System.out.println("after " + name); 26 | return val; 27 | } 28 | 29 | public void setProxy(Object proxy) { 30 | this.proxy = proxy; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/generic/CheckedList.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.generic; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | /** 8 | * @author lixinjie 9 | * @since 2018-07-10 10 | */ 11 | public class CheckedList { 12 | 13 | static class A {} 14 | static class B {} 15 | 16 | static void test1() { 17 | List al = new ArrayList<>(); 18 | al.add(new A()); 19 | ((List)al).add(new B()); 20 | //al.forEach(System.out::println); 21 | al.forEach((Object o) -> System.out.println(o)); 22 | } 23 | 24 | static void test2() { 25 | List al = new ArrayList<>(); 26 | List cal = Collections.checkedList(al, A.class); 27 | cal.add(new A()); 28 | ((List)cal).add(new B()); 29 | //al.forEach(System.out::println); 30 | al.forEach((Object o) -> System.out.println(o)); 31 | } 32 | 33 | public static void main(String[] args) { 34 | //test1(); 35 | test2(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/thread/rwlock/RDLock.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.thread.rwlock; 2 | 3 | import static org.cnt.java.utils.Methods.*; 4 | import java.util.concurrent.locks.Lock; 5 | import java.util.concurrent.locks.ReentrantReadWriteLock; 6 | 7 | /** 8 | * @author lixinjie 9 | * @since 2019-06-15 10 | */ 11 | public class RDLock { 12 | 13 | public static void main(String[] args) { 14 | 15 | ReentrantReadWriteLock rwlock = new ReentrantReadWriteLock(); 16 | Lock rlock = rwlock.readLock(); 17 | Lock wlock = rwlock.writeLock(); 18 | if (rlock.tryLock()) { 19 | println3("readlock"); 20 | if (wlock.tryLock()) { 21 | println3("writelock"); 22 | wlock.unlock(); 23 | } 24 | rlock.unlock(); 25 | } 26 | println3("----------------"); 27 | if (wlock.tryLock()) { 28 | println3("writelock"); 29 | if (rlock.tryLock()) { 30 | println3("readlock"); 31 | rlock.unlock(); 32 | } 33 | wlock.unlock(); 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/i/ITest.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.i; 2 | 3 | import java.lang.reflect.AnnotatedElement; 4 | import java.util.Arrays; 5 | 6 | import org.cnt.java.utils.Logger; 7 | 8 | /** 9 | * @author lixinjie 10 | * @since 2019-07-26 11 | */ 12 | public class ITest { 13 | 14 | static Logger log = Logger.getLogger(); 15 | 16 | public static void main(String[] args) { 17 | test(); 18 | } 19 | 20 | static void test() { 21 | AnnotatedElement ae1 = I1.class; 22 | AnnotatedElement ae2 = I2.class; 23 | 24 | log.info("getAnnotations={}", Arrays.toString(ae1.getAnnotations())); 25 | log.info("getAnnotations={}", Arrays.toString(ae2.getAnnotations())); 26 | 27 | log.info("getDeclaredAnnotations={}", Arrays.toString(ae1.getDeclaredAnnotations())); 28 | log.info("getDeclaredAnnotations={}", Arrays.toString(ae2.getDeclaredAnnotations())); 29 | 30 | //result:子接口不从父接口继承注解 31 | //note:@Inherited注解规定,只能用于子类从父类继承,其它情况不起作用 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/generic/TypeBound.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.generic; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2018-07-06 6 | */ 7 | public class TypeBound { 8 | 9 | static class CA { 10 | public void ca() { 11 | System.out.println("CA.ca"); 12 | } 13 | } 14 | 15 | interface IB { 16 | void ib(); 17 | } 18 | 19 | interface IC { 20 | void ic(); 21 | } 22 | 23 | static class E { 24 | 25 | public void e(T t) { 26 | t.ca(); 27 | t.ib(); 28 | t.ic(); 29 | } 30 | } 31 | 32 | static class D extends CA implements IB, IC { 33 | 34 | @Override 35 | public void ic() { 36 | System.out.println("IC.ic"); 37 | } 38 | 39 | @Override 40 | public void ib() { 41 | System.out.println("IB.ib"); 42 | } 43 | 44 | } 45 | 46 | public static void main(String[] args) { 47 | // E e1 = new E<>(); 48 | // E e2 = new E<>(); 49 | // E e3 = new E<>(); 50 | E e = new E<>(); 51 | e.e(new D()); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/f/FTest.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.f; 2 | 3 | import java.lang.reflect.AnnotatedElement; 4 | import java.util.Arrays; 5 | 6 | import org.cnt.java.utils.Logger; 7 | 8 | /** 9 | * @author lixinjie 10 | * @since 2019-07-26 11 | */ 12 | public class FTest { 13 | 14 | static Logger log = Logger.getLogger(); 15 | 16 | public static void main(String[] args) { 17 | test(); 18 | } 19 | 20 | static void test() { 21 | try { 22 | AnnotatedElement ae1 = F2.class.getField("f1"); 23 | 24 | log.info("getAnnotations={}", Arrays.toString(ae1.getAnnotations())); 25 | log.info("getDeclaredAnnotations={}", Arrays.toString(ae1.getDeclaredAnnotations())); 26 | 27 | AnnotatedElement ae2 = F2.class.getField("f2"); 28 | 29 | log.info("getAnnotations={}", Arrays.toString(ae2.getAnnotations())); 30 | log.info("getDeclaredAnnotations={}", Arrays.toString(ae2.getDeclaredAnnotations())); 31 | 32 | //result:子类原封不动继承父类字段时,自然可以得到字段上的注解 33 | //note:@Inherited注解规定,只能用于子类从父类继承,其它情况不起作用 34 | } catch (Exception e) { 35 | e.printStackTrace(); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/generic/UnboundTypeParam.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.generic; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @author lixinjie 8 | * @since 2018-07-10 9 | */ 10 | public class UnboundTypeParam { 11 | 12 | // static void test(List list) { 13 | // 14 | // } 15 | // 16 | // static void test(List list) { 17 | // 18 | // } 19 | // 20 | // static void test(List list) { 21 | // 22 | // } 23 | // 24 | // static void test(List list) { 25 | // 26 | // } 27 | 28 | public static void main(String[] args) { 29 | List l1 = new ArrayList<>(); 30 | List l2 = new ArrayList<>(); 31 | List l3 = new ArrayList<>(); 32 | List l4 = new ArrayList<>(); 33 | 34 | l1 = l2; 35 | l1 = l3; 36 | l1 = l4; 37 | 38 | l2 = l1; 39 | l2 = l3; 40 | l2 = l4; 41 | 42 | l3 = l1; 43 | l3 = l2; 44 | l3 = l4; 45 | 46 | l4 = l1; 47 | // l4 = l2; 48 | // l4 = l3; 49 | 50 | // l2.add(new Object());//?表示一种确定的类型,但不知道是什么类型,所以任何类型都不许添加 51 | l2.get(0);//?表示一种确定的类型,但不知道是什么类型,所以只能按Object类型对待 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/m/MTest.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.m; 2 | 3 | import java.lang.reflect.AnnotatedElement; 4 | import java.util.Arrays; 5 | 6 | import org.cnt.java.utils.Logger; 7 | 8 | /** 9 | * @author lixinjie 10 | * @since 2019-07-26 11 | */ 12 | public class MTest { 13 | 14 | static Logger log = Logger.getLogger(); 15 | 16 | public static void main(String[] args) { 17 | test(); 18 | } 19 | 20 | static void test() { 21 | try { 22 | AnnotatedElement ae1 = M2.class.getDeclaredMethod("m1"); 23 | 24 | log.info("getAnnotations={}", Arrays.toString(ae1.getAnnotations())); 25 | log.info("getDeclaredAnnotations={}", Arrays.toString(ae1.getDeclaredAnnotations())); 26 | 27 | AnnotatedElement ae2 = M2.class.getMethod("m2"); 28 | 29 | log.info("getAnnotations={}", Arrays.toString(ae2.getAnnotations())); 30 | log.info("getDeclaredAnnotations={}", Arrays.toString(ae2.getDeclaredAnnotations())); 31 | 32 | //result:子类重写父类方法时不继承父类方法的注解 33 | // 子类原封不动继承父类方法时,自然可以得到方法上的注解 34 | //note:@Inherited注解规定,只能用于子类从父类继承,其它情况不起作用 35 | } catch (Exception e) { 36 | e.printStackTrace(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/generic/Generic.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.generic; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.Method; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * @author lixinjie 10 | * @since 2019-07-18 11 | */ 12 | public class Generic { 13 | 14 | protected List strList = new ArrayList<>(); 15 | 16 | protected List intMethod() { 17 | return null; 18 | } 19 | 20 | public static void main(String[] args) { 21 | try { 22 | Field field = Generic.class.getDeclaredField("strList"); 23 | System.out.println(field.getType()); 24 | System.out.println(field.getGenericType()); 25 | System.out.println(field.getAnnotatedType().getType()); 26 | Class clazz = new Generic().strList.getClass(); 27 | System.out.println(clazz.toGenericString()); 28 | System.out.println(clazz.getTypeName()); 29 | System.out.println(clazz.getTypeParameters()[0]); 30 | Method method = Generic.class.getDeclaredMethod("intMethod"); 31 | System.out.println(method.getReturnType()); 32 | System.out.println(method.getGenericReturnType()); 33 | } catch (Exception e) { 34 | e.printStackTrace(); 35 | } 36 | 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/generic/TypeParam.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.generic; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * @author lixinjie 7 | * @since 2018-07-06 8 | */ 9 | public class TypeParam { 10 | 11 | public void printTypeInfo1() { 12 | System.out.println(Arrays.asList(this.getClass().getTypeParameters())); 13 | } 14 | 15 | public static void printTypeInfo2() { 16 | System.out.println(Arrays.asList(TypeParam.class.getTypeParameters())); 17 | } 18 | 19 | public void testType(Object obj) { 20 | // System.out.println(obj instanceof T); 21 | // System.out.println(obj instanceof R); 22 | // System.out.println(new T()); 23 | // System.out.println(new R()); 24 | } 25 | 26 | public void testArray() { 27 | 28 | } 29 | 30 | public static void main(String[] args) { 31 | new TypeParam().printTypeInfo1(); 32 | new TypeParam().printTypeInfo1(); 33 | TypeParam.printTypeInfo2(); 34 | 35 | System.out.println(new TypeParam().getClass() == new TypeParam().getClass()); 36 | System.out.println(TypeParam.class == new TypeParam().getClass()); 37 | System.out.println(new TypeParam().getClass() == new TypeParam().getClass()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/io/bio/Client.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.io.bio; 2 | 3 | import java.io.IOException; 4 | import java.net.InetSocketAddress; 5 | import java.net.Socket; 6 | import java.util.Random; 7 | 8 | /** 9 | * @author lixinjie 10 | * @since 2019-05-07 11 | */ 12 | public class Client { 13 | 14 | public static void main(String[] args) { 15 | try { 16 | for (int i = 0; i < 20; i++) { 17 | Socket s = new Socket(); 18 | s.connect(new InetSocketAddress("localhost", 8080)); 19 | processWithNewThread(s, i); 20 | } 21 | } catch (IOException e) { 22 | e.printStackTrace(); 23 | } 24 | } 25 | 26 | static void processWithNewThread(Socket s, int i) { 27 | Runnable run = () -> { 28 | try { 29 | //睡眠随机的5-10秒,模拟数据尚未就绪 30 | Thread.sleep((new Random().nextInt(6) + 5) * 1000); 31 | //写1M数据,为了拉长服务器端读数据的过程 32 | s.getOutputStream().write(prepareBytes()); 33 | //睡眠1秒,让服务器端把数据读完 34 | Thread.sleep(1000); 35 | s.close(); 36 | } catch (Exception e) { 37 | e.printStackTrace(); 38 | } 39 | }; 40 | new Thread(run).start(); 41 | } 42 | 43 | static byte[] prepareBytes() { 44 | byte[] bytes = new byte[1024*1024*1]; 45 | for (int i = 0; i < bytes.length; i++) { 46 | bytes[i] = 1; 47 | } 48 | return bytes; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/utils/Logger.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.utils; 2 | 3 | import java.time.LocalDateTime; 4 | import java.time.format.DateTimeFormatter; 5 | 6 | /** 7 | * @author lixinjie 8 | * @since 2019-07-08 9 | */ 10 | public class Logger { 11 | 12 | public static DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); 13 | 14 | private Logger() { 15 | } 16 | 17 | public static Logger getLogger() { 18 | return new Logger(); 19 | } 20 | 21 | public void info(String format, Object... params) { 22 | StackTraceElement ste = new Exception().getStackTrace()[1]; 23 | format = format.replaceAll("\\{\\}", "%s"); 24 | format = "%s [INFO] " + format + " - %s.%s(%s:%d)"; 25 | System.out.println(String.format(format, buildParams(params, ste))); 26 | } 27 | 28 | public static String time() { 29 | return LocalDateTime.now().format(dtf); 30 | } 31 | 32 | public static Object[] buildParams(Object[] params, StackTraceElement ste) { 33 | Object[] ps = new Object[params.length + 5]; 34 | ps[0] = time(); 35 | for (int i = 0; i < params.length; i++) { 36 | ps[i + 1] = params[i]; 37 | } 38 | ps[ps.length - 4] = ste.getClassName(); 39 | ps[ps.length - 3] = ste.getMethodName(); 40 | ps[ps.length - 2] = ste.getFileName(); 41 | ps[ps.length - 1] = ste.getLineNumber(); 42 | return ps; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/ci/CITest.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.ci; 2 | 3 | import java.lang.reflect.AnnotatedElement; 4 | import java.util.Arrays; 5 | 6 | import org.cnt.java.utils.Logger; 7 | 8 | /** 9 | * @author lixinjie 10 | * @since 2019-07-26 11 | */ 12 | public class CITest { 13 | 14 | static Logger log = Logger.getLogger(); 15 | 16 | public static void main(String[] args) { 17 | test(); 18 | log.info("--------------------------------------------------------"); 19 | test1(); 20 | } 21 | 22 | static void test() { 23 | AnnotatedElement ae1 = CI1.class; 24 | 25 | log.info("getAnnotations={}", Arrays.toString(ae1.getAnnotations())); 26 | log.info("getDeclaredAnnotations={}", Arrays.toString(ae1.getDeclaredAnnotations())); 27 | 28 | //result:类不从它实现的接口继承注解 29 | //note:@Inherited注解规定,只能用于子类从父类继承,其它情况不起作用 30 | } 31 | 32 | static void test1() { 33 | try { 34 | AnnotatedElement ae1 = CI1.class.getDeclaredMethod("m1"); 35 | 36 | log.info("getAnnotations={}", Arrays.toString(ae1.getAnnotations())); 37 | log.info("getDeclaredAnnotations={}", Arrays.toString(ae1.getDeclaredAnnotations())); 38 | 39 | AnnotatedElement ae2 = CI1.class.getDeclaredMethod("m2"); 40 | 41 | log.info("getAnnotations={}", Arrays.toString(ae2.getAnnotations())); 42 | log.info("getDeclaredAnnotations={}", Arrays.toString(ae2.getDeclaredAnnotations())); 43 | 44 | //result:类在实现接口方法时不继承接口方法的注解 45 | //note:@Inherited注解规定,只能用于子类从父类继承,其它情况不起作用 46 | } catch (Exception e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/thread/coop/ThreadCo3.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.thread.coop; 2 | 3 | import static org.cnt.java.utils.Methods.doingLongTime; 4 | import static org.cnt.java.utils.Methods.println; 5 | 6 | import java.util.concurrent.Exchanger; 7 | /** 8 | * @author lixinjie 9 | * @since 2019-05-25 10 | */ 11 | public class ThreadCo3 { 12 | 13 | public static void main(String[] args) throws Exception { 14 | new Thread(new Staff("大胖", new Tool("笤帚", "扫地"), ex)).start(); 15 | new Thread(new Staff("小白", new Tool("抹布", "擦桌"), ex)).start(); 16 | synchronized (ThreadCo3.class) { 17 | ThreadCo3.class.wait(); 18 | } 19 | } 20 | 21 | static Exchanger ex = new Exchanger<>(); 22 | 23 | static class Staff implements Runnable { 24 | 25 | String name; 26 | Tool tool; 27 | Exchanger ex; 28 | 29 | Staff(String name, Tool tool, Exchanger ex) { 30 | this.name = name; 31 | this.tool = tool; 32 | this.ex = ex; 33 | } 34 | 35 | @Override 36 | public void run() { 37 | println("%s拿的工具是[%s],他开始[%s]。。。", name, tool.name, tool.work); 38 | doingLongTime(); 39 | println("%s开始交换工具。。。", name); 40 | try { 41 | tool = ex.exchange(tool); 42 | } catch (Exception e) { 43 | e.printStackTrace(); 44 | } 45 | 46 | println("%s的工具变为[%s],他开始[%s]。。。", name, tool.name, tool.work); 47 | } 48 | 49 | } 50 | 51 | static class Tool { 52 | 53 | String name; 54 | String work; 55 | 56 | Tool(String name, String work) { 57 | this.name = name; 58 | this.work = work; 59 | } 60 | 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/jdkproxy/JpMain.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.jdkproxy; 2 | 3 | import java.lang.reflect.Proxy; 4 | 5 | /** 6 | * @author lixinjie 7 | * @since 2020-07-03 8 | */ 9 | public class JpMain { 10 | 11 | public static void main(String[] args) { 12 | test1(); 13 | System.out.println("\r\n--------\r\n"); 14 | test2(); 15 | } 16 | 17 | static void test2() { 18 | ClassAB classAB = new ClassAB(); 19 | Object proxyObj = Proxy.newProxyInstance(JpMain.class.getClassLoader(), 20 | new Class[] { InterA.class, InterB.class }, 21 | (proxy, method, args) -> { 22 | String name = method.getName(); 23 | System.out.println("before " + name); 24 | Object val = method.invoke(classAB, args); 25 | System.out.println("after " + name); 26 | return val; 27 | }); 28 | InterA ia = (InterA)proxyObj; 29 | InterB ib = (InterB)proxyObj; 30 | ia.methodA1(); 31 | ia.methodA2(); 32 | ib.methodB1(); 33 | ib.methodB2(); 34 | } 35 | 36 | static void test1() { 37 | ClassAB classAB = new ClassAB(); 38 | ActualHandler ah = new ActualHandler(classAB); 39 | Object proxy = Proxy.newProxyInstance(JpMain.class.getClassLoader(), new Class[] { InterA.class, InterB.class }, ah); 40 | ah.setProxy(proxy); 41 | 42 | System.out.println("classAB == proxy : " + (classAB == proxy)); 43 | 44 | classAB.methodA1(); 45 | classAB.methodA2(); 46 | classAB.methodB1(); 47 | classAB.methodB2(); 48 | System.out.println(); 49 | InterA ia = (InterA)proxy; 50 | InterB ib = (InterB)proxy; 51 | ia.methodA1(); 52 | ia.methodA2(); 53 | ib.methodB1(); 54 | ib.methodB2(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/generic/ArrayCvCtv.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.generic; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2018-07-09 6 | */ 7 | public class ArrayCvCtv { 8 | 9 | static class Employee {} 10 | static class Teamleader extends Employee {} 11 | static class Manager extends Teamleader {} 12 | static class Boss extends Manager {} 13 | 14 | static void test1() { 15 | Employee[] es = new Employee[10]; 16 | es[0] = new Employee(); 17 | es[1] = new Teamleader(); 18 | es[2] = new Manager(); 19 | es[3] = new Boss(); 20 | } 21 | 22 | static void test2() { 23 | Teamleader[] ts = new Teamleader[10]; 24 | ts[1] = new Teamleader(); 25 | ts[2] = new Manager(); 26 | ts[3] = new Boss(); 27 | Employee[] ets = ts; 28 | Employee ets1 = ets[1]; 29 | Employee ets2 = ets[2]; 30 | Employee ets3 = ets[3]; 31 | //读数据没问题 32 | ets[0] = new Employee();//可以编译,运行报错 33 | ets[1] = new Teamleader(); 34 | ets[2] = new Manager(); 35 | ets[3] = new Boss(); 36 | //写数据可能报错,且编译器不提示 37 | /**适合往外读数据*/ 38 | } 39 | 40 | static void test3() { 41 | Employee[] es = new Employee[10]; 42 | es[0] = new Employee(); 43 | es[1] = new Teamleader(); 44 | es[2] = new Manager(); 45 | es[3] = new Boss(); 46 | Teamleader[] ts = (Teamleader[])es; 47 | Teamleader ts0 = ts[0];//可以编译,运行报错 48 | Teamleader ts1 = ts[1]; 49 | Teamleader ts2 = ts[2]; 50 | Teamleader ts3 = ts[3]; 51 | //读数据可能报错,且编译器不提示 52 | ts[1] = new Teamleader(); 53 | ts[2] = new Manager(); 54 | ts[3] = new Boss(); 55 | //写数据没问题 56 | /**适合往里写入数据*/ 57 | } 58 | 59 | public static void main(String[] args) { 60 | test1(); 61 | test2(); 62 | test3(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/thread/coop/ThreadCo1.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.thread.coop; 2 | 3 | import static org.cnt.java.utils.Methods.doingLongTime; 4 | import static org.cnt.java.utils.Methods.println; 5 | import static org.cnt.java.utils.Methods.sleep; 6 | 7 | import java.util.concurrent.CountDownLatch; 8 | 9 | /** 10 | * @author lixinjie 11 | * @since 2019-05-24 12 | */ 13 | public class ThreadCo1 { 14 | 15 | static final int COUNT = 20; 16 | 17 | public static void main(String[] args) throws Exception { 18 | new Thread(new Teacher(cdl)).start(); 19 | sleep(1); 20 | for (int i = 0; i < COUNT; i++) { 21 | new Thread(new Student(i, cdl)).start(); 22 | } 23 | synchronized (ThreadCo1.class) { 24 | ThreadCo1.class.wait(); 25 | } 26 | } 27 | 28 | static CountDownLatch cdl = new CountDownLatch(COUNT); 29 | 30 | static class Teacher implements Runnable { 31 | 32 | CountDownLatch cdl; 33 | 34 | Teacher(CountDownLatch cdl) { 35 | this.cdl = cdl; 36 | } 37 | 38 | @Override 39 | public void run() { 40 | println("老师发卷子。。。"); 41 | try { 42 | cdl.await(); 43 | } catch (InterruptedException e) { 44 | e.printStackTrace(); 45 | } 46 | println("老师收卷子。。。"); 47 | } 48 | 49 | } 50 | 51 | static class Student implements Runnable { 52 | 53 | CountDownLatch cdl; 54 | int num; 55 | 56 | Student(int num, CountDownLatch cdl) { 57 | this.num = num; 58 | this.cdl = cdl; 59 | } 60 | 61 | @Override 62 | public void run() { 63 | println("学生(%d)写卷子。。。", num); 64 | doingLongTime(); 65 | println("学生(%d)交卷子。。。", num); 66 | cdl.countDown(); 67 | } 68 | 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/utils/Methods.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.utils; 2 | 3 | import java.time.LocalTime; 4 | import java.time.format.DateTimeFormatter; 5 | import java.util.Random; 6 | import java.util.concurrent.TimeUnit; 7 | 8 | /** 9 | * @author lixinjie 10 | * @since 2019-05-25 11 | */ 12 | public class Methods { 13 | 14 | public static DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm:ss"); 15 | 16 | public static int random(int max) { 17 | return random(0, max); 18 | } 19 | 20 | public static int random(int min, int max) { 21 | return min + new Random().nextInt(max - min + 1); 22 | } 23 | 24 | public static void doingLongTime() { 25 | int second = random(5, 10); 26 | sleep(second); 27 | } 28 | 29 | public static void doingLongTime(int second) { 30 | sleep(second); 31 | } 32 | 33 | public static void sleep(int second) { 34 | try { 35 | TimeUnit.SECONDS.sleep(second); 36 | } catch (InterruptedException e) { 37 | e.printStackTrace(); 38 | } 39 | } 40 | 41 | public static void sleep2(int second) throws InterruptedException { 42 | TimeUnit.SECONDS.sleep(second); 43 | } 44 | 45 | public static void println3(Object obj) { 46 | System.out.println(time() + ", " + obj); 47 | } 48 | 49 | public static void println2(String text, Object... args) { 50 | System.out.println(String.format(text, args)); 51 | } 52 | 53 | public static void println(String text, Object... args) { 54 | System.out.println(String.format(time() + ", " + text, args)); 55 | } 56 | 57 | public static void println(Object obj) { 58 | System.out.println(obj); 59 | } 60 | 61 | public static String time() { 62 | return LocalTime.now().format(dtf); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/thread/coop/ThreadCo2.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.thread.coop; 2 | 3 | import static org.cnt.java.utils.Methods.doingLongTime; 4 | import static org.cnt.java.utils.Methods.println; 5 | 6 | import java.util.concurrent.CyclicBarrier; 7 | 8 | /** 9 | * @author lixinjie 10 | * @since 2019-05-24 11 | */ 12 | public class ThreadCo2 { 13 | 14 | static final int COUNT = 5; 15 | 16 | public static void main(String[] args) throws Exception { 17 | for (int i = 0; i < COUNT; i++) { 18 | new Thread(new Staff(i, cb)).start(); 19 | } 20 | synchronized (ThreadCo2.class) { 21 | ThreadCo2.class.wait(); 22 | } 23 | } 24 | 25 | static CyclicBarrier cb = new CyclicBarrier(COUNT, new Singer()); 26 | 27 | static class Singer implements Runnable { 28 | 29 | @Override 30 | public void run() { 31 | println("为大家唱歌。。。"); 32 | } 33 | 34 | } 35 | 36 | static class Staff implements Runnable { 37 | 38 | CyclicBarrier cb; 39 | int num; 40 | 41 | Staff(int num, CyclicBarrier cb) { 42 | this.num = num; 43 | this.cb = cb; 44 | } 45 | 46 | @Override 47 | public void run() { 48 | println("员工(%d)出发。。。", num); 49 | doingLongTime(); 50 | println("员工(%d)到达地点一。。。", num); 51 | try { 52 | cb.await(); 53 | } catch (Exception e) { 54 | e.printStackTrace(); 55 | } 56 | println("员工(%d)再出发。。。", num); 57 | doingLongTime(); 58 | println("员工(%d)到达地点二。。。", num); 59 | try { 60 | cb.await(); 61 | } catch (Exception e) { 62 | e.printStackTrace(); 63 | } 64 | println("员工(%d)再出发。。。", num); 65 | doingLongTime(); 66 | println("员工(%d)到达地点三。。。", num); 67 | try { 68 | cb.await(); 69 | } catch (Exception e) { 70 | e.printStackTrace(); 71 | } 72 | println("员工(%d)结束。。。", num); 73 | } 74 | 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/io/bio/BioServer.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.io.bio; 2 | 3 | import java.io.InputStream; 4 | import java.net.InetSocketAddress; 5 | import java.net.ServerSocket; 6 | import java.net.Socket; 7 | import java.text.SimpleDateFormat; 8 | import java.util.Date; 9 | import java.util.concurrent.atomic.AtomicInteger; 10 | 11 | /** 12 | * @author lixinjie 13 | * @since 2019-05-07 14 | */ 15 | public class BioServer { 16 | 17 | static AtomicInteger counter = new AtomicInteger(0); 18 | static SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); 19 | 20 | public static void main(String[] args) { 21 | try { 22 | ServerSocket ss = new ServerSocket(); 23 | ss.bind(new InetSocketAddress("localhost", 8080)); 24 | while (true) { 25 | Socket s = ss.accept(); 26 | processWithNewThread(s); 27 | } 28 | } catch (Exception e) { 29 | e.printStackTrace(); 30 | } 31 | } 32 | 33 | static void processWithNewThread(Socket s) { 34 | Runnable run = () -> { 35 | InetSocketAddress rsa = (InetSocketAddress)s.getRemoteSocketAddress(); 36 | System.out.println(time() + "->" + rsa.getHostName() + ":" + rsa.getPort() + "->" + Thread.currentThread().getId() + ":" + counter.incrementAndGet()); 37 | try { 38 | String result = readBytes(s.getInputStream()); 39 | System.out.println(time() + "->" + result + "->" + Thread.currentThread().getId() + ":" + counter.getAndDecrement()); 40 | s.close(); 41 | } catch (Exception e) { 42 | e.printStackTrace(); 43 | } 44 | }; 45 | new Thread(run).start(); 46 | } 47 | 48 | static String readBytes(InputStream is) throws Exception { 49 | long start = 0; 50 | int total = 0; 51 | int count = 0; 52 | byte[] bytes = new byte[1024]; 53 | //开始读数据的时间 54 | long begin = System.currentTimeMillis(); 55 | while ((count = is.read(bytes)) > -1) { 56 | if (start < 1) { 57 | //第一次读到数据的时间 58 | start = System.currentTimeMillis(); 59 | } 60 | total += count; 61 | } 62 | //读完数据的时间 63 | long end = System.currentTimeMillis(); 64 | return "wait=" + (start - begin) + "ms,read=" + (end - start) + "ms,total=" + total + "bs"; 65 | } 66 | 67 | static String time() { 68 | return sdf.format(new Date()); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/utils/Byter.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.utils; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-07-09 6 | */ 7 | public class Byter { 8 | 9 | 10 | public static int toUnsigned(byte[] bytes, int offset, int length) { 11 | if (length == 1) { 12 | return toUnsigned(bytes[offset]); 13 | } 14 | if (length == 2) { 15 | return toUnsigned(bytes[offset], bytes[offset + 1]); 16 | } 17 | return -1; 18 | } 19 | 20 | public static long toUnsignedLong(byte[] bytes, int offset, int length) { 21 | if (length == 1 || length == 2) { 22 | return toUnsigned(bytes, offset, length); 23 | } 24 | if (length == 4) { 25 | return toUnsigned(bytes[offset], bytes[offset + 1], bytes[offset + 2], bytes[offset + 3]); 26 | } 27 | return -1; 28 | } 29 | 30 | public static String toString(byte[] bytes, int offset, int length) { 31 | return new String(bytes, offset, length); 32 | } 33 | 34 | public static int toUnsigned(byte b) { 35 | //把一个byte原样不变的放到int 36 | //类型的第4个字节位置,且前面 37 | //3个字节都清空为0 38 | return b & 0xff; 39 | } 40 | 41 | public static int toUnsigned(byte b1, byte b0) { 42 | return toUnsigned(b1) << 8 | toUnsigned(b0); 43 | } 44 | 45 | public static long toUnsigned(byte b3, byte b2, byte b1, byte b0) { 46 | return (long)toUnsigned(b3) << 24 | toUnsigned(b2) << 16 | toUnsigned(b1) << 8 | toUnsigned(b0); 47 | } 48 | 49 | public static int toSigned(byte b) { 50 | //把一个byte原样不变的放到int 51 | //类型的第4个字节位置,且前面 52 | //3个字节都填充为byte的符号位 53 | return b; 54 | } 55 | 56 | public static int toSigned(byte b1, byte b0) { 57 | return toSigned(b1) << 8 | toUnsigned(b0); 58 | } 59 | 60 | public static int toSigned(byte b3, byte b2, byte b1, byte b0) { 61 | return toSigned(b3) << 24 | toUnsigned(b2) << 16 | toUnsigned(b1) << 8 | toUnsigned(b0); 62 | } 63 | 64 | public static long toSigned(byte b7, byte b6, byte b5, byte b4, byte b3, byte b2, byte b1, byte b0) { 65 | return (long)toSigned(b7) << 56 | (long)toUnsigned(b6) << 48 | (long)toUnsigned(b5) << 40 | (long)toUnsigned(b4) << 32 66 | | (long)toUnsigned(b3) << 24 | toUnsigned(b2) << 16 | toUnsigned(b1) << 8 | toUnsigned(b0); 67 | } 68 | 69 | public static void main(String[] args) { 70 | 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/thread/coop/ThreadCo4.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.thread.coop; 2 | 3 | import static org.cnt.java.utils.Methods.doingLongTime; 4 | import static org.cnt.java.utils.Methods.println; 5 | import static org.cnt.java.utils.Methods.println2; 6 | import static org.cnt.java.utils.Methods.random; 7 | 8 | import java.util.concurrent.Phaser; 9 | 10 | /** 11 | * @author lixinjie 12 | * @since 2019-05-25 13 | */ 14 | public class ThreadCo4 { 15 | 16 | static final int COUNT = 6; 17 | 18 | public static void main(String[] args) throws Exception { 19 | new Thread(new Challenger("张三")).start(); 20 | new Thread(new Challenger("李四")).start(); 21 | new Thread(new Challenger("王五")).start(); 22 | new Thread(new Challenger("赵六")).start(); 23 | new Thread(new Challenger("大胖")).start(); 24 | new Thread(new Challenger("小白")).start(); 25 | synchronized (ThreadCo4.class) { 26 | ThreadCo4.class.wait(); 27 | } 28 | } 29 | 30 | static Phaser ph = new Phaser() { 31 | 32 | protected boolean onAdvance(int phase, int registeredParties) { 33 | println2("第(%d)局,剩余[%d]人", phase, registeredParties); 34 | return registeredParties == 0 || 35 | (phase != 0 && registeredParties == COUNT); 36 | }; 37 | }; 38 | 39 | static class Challenger implements Runnable { 40 | 41 | String name; 42 | int state; 43 | 44 | Challenger(String name) { 45 | this.name = name; 46 | this.state = 0; 47 | } 48 | 49 | @Override 50 | public void run() { 51 | println("[%s]开始挑战。。。", name); 52 | ph.register(); 53 | int phase = 0; 54 | int h; 55 | while (!ph.isTerminated() && phase < 100) { 56 | doingLongTime(5); 57 | if (state == 0) { 58 | if (Decide.goon()) { 59 | h = ph.arriveAndAwaitAdvance(); 60 | if (h < 0) 61 | println("No%d.[%s]继续,但已胜利。。。", phase, name); 62 | else 63 | println("No%d.[%s]继续at(%d)。。。", phase, name, h); 64 | } else { 65 | state = -1; 66 | h = ph.arriveAndDeregister(); 67 | println("No%d.[%s]退出at(%d)。。。", phase, name, h); 68 | } 69 | } else { 70 | if (Decide.revive()) { 71 | state = 0; 72 | h = ph.register(); 73 | if (h < 0) 74 | println("No%d.[%s]复活,但已失败。。。", phase, name); 75 | else 76 | println("No%d.[%s]复活at(%d)。。。", phase, name, h); 77 | } else { 78 | println("No%d.[%s]没有复活。。。", phase, name); 79 | } 80 | } 81 | phase++; 82 | } 83 | if (state == 0) { 84 | ph.arriveAndDeregister(); 85 | } 86 | println("[%s]结束。。。", name); 87 | } 88 | 89 | } 90 | 91 | static class Decide { 92 | 93 | static boolean goon() { 94 | return random(9) > 4; 95 | } 96 | 97 | static boolean revive() { 98 | return random(9) < 5; 99 | } 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/filechannel/FcMain.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.filechannel; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | import java.nio.channels.SeekableByteChannel; 6 | import java.nio.charset.StandardCharsets; 7 | import java.nio.file.Files; 8 | import java.nio.file.Path; 9 | import java.nio.file.Paths; 10 | import java.nio.file.StandardOpenOption; 11 | import java.util.Arrays; 12 | 13 | /** 14 | * @author lixinjie 15 | * @since 2020-07-03 16 | */ 17 | public class FcMain { 18 | 19 | static final byte BLANK = 32; 20 | static final String NEWLINE_STRING = System.getProperty("line.separator"); 21 | static final byte[] NEWLINE_BYTES = NEWLINE_STRING.getBytes(StandardCharsets.UTF_8); 22 | static final byte[] EMTPY_BYTES = new byte[0]; 23 | static final int NEWLINE_LENGTH = NEWLINE_BYTES.length; 24 | static final int CONTENT_LENGTH = 60; 25 | static final int LINE_LENGTH = CONTENT_LENGTH + NEWLINE_LENGTH; 26 | 27 | public static void main(String[] args) throws IOException { 28 | String file = "D:/article.list"; 29 | Path path = Paths.get(file); 30 | //write(path); 31 | replace(path); 32 | read(path); 33 | } 34 | 35 | static void read(Path path) throws IOException { 36 | SeekableByteChannel channel = Files.newByteChannel(path, StandardOpenOption.READ); 37 | channel.position(LINE_LENGTH * 0); 38 | System.out.println(channel.size()); 39 | ByteBuffer bb = ByteBuffer.allocate((int) channel.size() + 1); 40 | bb.clear(); 41 | while (channel.read(bb) != -1) { }; 42 | bb.flip(); 43 | byte[] bytes = new byte[bb.remaining()]; 44 | bb.get(bytes, 0, bytes.length); 45 | System.out.println(new String(bytes, StandardCharsets.UTF_8)); 46 | } 47 | 48 | static void write(Path path) throws IOException { 49 | SeekableByteChannel channel = Files.newByteChannel(path, StandardOpenOption.CREATE, StandardOpenOption.WRITE); 50 | byte[] bytes = "happy weekend".getBytes(StandardCharsets.UTF_8); 51 | ByteBuffer bb = ByteBuffer.allocate(LINE_LENGTH); 52 | bb.put(bytes); 53 | bb.put(getBlanks(CONTENT_LENGTH - bytes.length)); 54 | bb.put(getNewLine()); 55 | channel.position(channel.size()); 56 | bb.flip(); 57 | channel.write(bb); 58 | } 59 | 60 | static void replace(Path path) throws IOException { 61 | SeekableByteChannel channel = Files.newByteChannel(path, StandardOpenOption.CREATE, StandardOpenOption.WRITE); 62 | byte[] bytes = "我爱你,我的祖国母亲!".getBytes(StandardCharsets.UTF_8); 63 | ByteBuffer bb = ByteBuffer.allocate(LINE_LENGTH); 64 | bb.put(bytes); 65 | channel.position(LINE_LENGTH * 1); 66 | bb.flip(); 67 | channel.write(bb); 68 | } 69 | 70 | static byte[] getBlanks(int count) { 71 | if (count == 0) { 72 | return EMTPY_BYTES; 73 | } 74 | byte[] blanks = new byte[count]; 75 | Arrays.fill(blanks, BLANK); 76 | return blanks; 77 | } 78 | 79 | static byte[] getNewLine() { 80 | return NEWLINE_BYTES; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/thread/prco/ProdCons.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.thread.prco; 2 | 3 | import static org.cnt.java.utils.Methods.doingLongTime; 4 | import static org.cnt.java.utils.Methods.println; 5 | import static org.cnt.java.utils.Methods.random; 6 | 7 | import java.util.concurrent.locks.Condition; 8 | import java.util.concurrent.locks.Lock; 9 | import java.util.concurrent.locks.ReentrantLock; 10 | 11 | /** 12 | * @author lixinjie 13 | * @since 2019-05-26 14 | */ 15 | public class ProdCons { 16 | 17 | public static void main(String[] args) { 18 | Queue queue = new Queue(); 19 | new Thread(new Producer(queue)).start(); 20 | new Thread(new Producer(queue)).start(); 21 | new Thread(new Consumer(queue)).start(); 22 | } 23 | 24 | static class Producer implements Runnable { 25 | 26 | Queue queue; 27 | 28 | Producer(Queue queue) { 29 | this.queue = queue; 30 | } 31 | 32 | @Override 33 | public void run() { 34 | try { 35 | for (int i = 0; i < 10000; i++) { 36 | doingLongTime(); 37 | queue.putEle(random(10000)); 38 | } 39 | } catch (Exception e) { 40 | e.printStackTrace(); 41 | } 42 | } 43 | 44 | } 45 | 46 | static class Consumer implements Runnable { 47 | 48 | Queue queue; 49 | 50 | Consumer(Queue queue) { 51 | this.queue = queue; 52 | } 53 | 54 | @Override 55 | public void run() { 56 | try { 57 | for (int i = 0; i < 10000; i++) { 58 | doingLongTime(); 59 | queue.takeEle(); 60 | } 61 | } catch (Exception e) { 62 | e.printStackTrace(); 63 | } 64 | } 65 | 66 | } 67 | 68 | static class Queue { 69 | Lock lock = new ReentrantLock(); 70 | Condition prodCond = lock.newCondition(); 71 | Condition consCond = lock.newCondition(); 72 | 73 | final int CAPACITY = 10; 74 | Object[] container = new Object[CAPACITY]; 75 | int count = 0; 76 | int putIndex = 0; 77 | int takeIndex = 0; 78 | 79 | public void putEle(Object ele) throws InterruptedException { 80 | try { 81 | lock.lock(); 82 | while (count == CAPACITY) { 83 | println("队列已满:%d,生产者开始睡大觉。。。", count); 84 | prodCond.await(); 85 | } 86 | container[putIndex] = ele; 87 | println("生产元素:%d", ele); 88 | putIndex++; 89 | if (putIndex >= CAPACITY) { 90 | putIndex = 0; 91 | } 92 | count++; 93 | println("通知消费者去消费。。。"); 94 | consCond.signalAll(); 95 | } finally { 96 | lock.unlock(); 97 | } 98 | } 99 | 100 | public Object takeEle() throws InterruptedException { 101 | try { 102 | lock.lock(); 103 | while (count == 0) { 104 | println("队列已空:%d,消费者开始睡大觉。。。", count); 105 | consCond.await(); 106 | } 107 | Object ele = container[takeIndex]; 108 | println("消费元素:%d", ele); 109 | takeIndex++; 110 | if (takeIndex >= CAPACITY) { 111 | takeIndex = 0; 112 | } 113 | count--; 114 | println("通知生产者去生产。。。"); 115 | prodCond.signalAll(); 116 | return ele; 117 | } finally { 118 | lock.unlock(); 119 | } 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/io/aio/AioServer.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.io.aio; 2 | 3 | import java.net.InetSocketAddress; 4 | import java.nio.ByteBuffer; 5 | import java.nio.channels.AsynchronousServerSocketChannel; 6 | import java.nio.channels.AsynchronousSocketChannel; 7 | import java.nio.channels.CompletionHandler; 8 | import java.text.SimpleDateFormat; 9 | import java.util.Date; 10 | import java.util.concurrent.atomic.AtomicInteger; 11 | 12 | /** 13 | * @author lixinjie 14 | * @since 2019-05-13 15 | */ 16 | public class AioServer { 17 | 18 | static int clientCount = 0; 19 | static AtomicInteger counter = new AtomicInteger(0); 20 | static SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); 21 | 22 | public static void main(String[] args) { 23 | try { 24 | AsynchronousServerSocketChannel assc = AsynchronousServerSocketChannel.open(); 25 | assc.bind(new InetSocketAddress("localhost", 8080)); 26 | //非阻塞方法,其实就是注册了个回调,而且只能接受一个连接 27 | assc.accept(null, new CompletionHandler() { 28 | 29 | @Override 30 | public void completed(AsynchronousSocketChannel asc, Object attachment) { 31 | //再次注册,接受下一个连接 32 | assc.accept(null, this); 33 | try { 34 | InetSocketAddress rsa = (InetSocketAddress)asc.getRemoteAddress(); 35 | System.out.println(time() + "->" + rsa.getHostName() + ":" + rsa.getPort() + "->" + Thread.currentThread().getId() + ":" + (++clientCount)); 36 | } catch (Exception e) { 37 | } 38 | readFromChannelAsync(asc); 39 | } 40 | 41 | @Override 42 | public void failed(Throwable exc, Object attachment) { 43 | 44 | } 45 | }); 46 | //不让主线程退出 47 | synchronized (AioServer.class) { 48 | AioServer.class.wait(); 49 | } 50 | } catch (Exception e) { 51 | e.printStackTrace(); 52 | } 53 | } 54 | 55 | static void readFromChannelAsync(AsynchronousSocketChannel asc) { 56 | //会把数据读入到该buffer之后,再触发工作线程来执行回调 57 | ByteBuffer bb = ByteBuffer.allocate(1024*1024*1 + 1); 58 | long begin = System.currentTimeMillis(); 59 | //非阻塞方法,其实就是注册了个回调,而且只能接受一次读取 60 | asc.read(bb, null, new CompletionHandler() { 61 | //从该连接上一共读到的字节数 62 | int total = 0; 63 | /** 64 | * @param count 表示本次读取到的字节数,-1表示数据已读完 65 | */ 66 | @Override 67 | public void completed(Integer count, Object attachment) { 68 | counter.incrementAndGet(); 69 | if (count > -1) { 70 | total += count; 71 | } 72 | int size = bb.position(); 73 | System.out.println(time() + "->count=" + count + ",total=" + total + "bs,buffer=" + size + "bs->" + Thread.currentThread().getId() + ":" + counter.get()); 74 | if (count > -1) {//数据还没有读完 75 | //再次注册回调,接受下一次读取 76 | asc.read(bb, null, this); 77 | } else {//数据已读完 78 | try { 79 | asc.close(); 80 | } catch (Exception e) { 81 | e.printStackTrace(); 82 | } 83 | } 84 | counter.decrementAndGet(); 85 | } 86 | 87 | @Override 88 | public void failed(Throwable exc, Object attachment) { 89 | 90 | } 91 | }); 92 | long end = System.currentTimeMillis(); 93 | System.out.println(time() + "->exe read req,use=" + (end -begin) + "ms" + "->" + Thread.currentThread().getId()); 94 | } 95 | 96 | static String time() { 97 | return sdf.format(new Date()); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/thread/obj/Obj.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.thread.obj; 2 | 3 | import static org.cnt.java.utils.Methods.*; 4 | 5 | /** 6 | * @author lixinjie 7 | * @since 2019-06-08 8 | */ 9 | public class Obj { 10 | 11 | public static void main(String[] args) { 12 | test1(); 13 | //test2(); 14 | //test3(); 15 | //test4(); 16 | } 17 | 18 | static void test1() { 19 | O o = new O("小白"); 20 | new Thread(new W(o):: run).start(); 21 | new Thread(new W(o):: run).start(); 22 | new Thread(new N(o):: run).start(); 23 | } 24 | 25 | static void test2() { 26 | O o = new O("大白"); 27 | new Thread(new W(o):: run).start(); 28 | new Thread(new W(o):: run).start(); 29 | new Thread(new W(o):: run).start(); 30 | new Thread(new W(o):: run).start(); 31 | new Thread(new N(o):: run2).start(); 32 | } 33 | 34 | static void test3() { 35 | O o = new O("老白"); 36 | new Thread(new W(o):: run2).start(); 37 | new Thread(new W(o):: run2).start(); 38 | new Thread(new W(o):: run2).start(); 39 | new Thread(new W(o):: run2).start(); 40 | } 41 | 42 | static void test4() { 43 | O o1 = new O("小白"); 44 | O o2 = new O("大白"); 45 | //在小白上等待 46 | new Thread(new W(o1):: run).start(); 47 | new Thread(new W(o1):: run).start(); 48 | new Thread(new W(o1):: run).start(); 49 | new Thread(new W(o1):: run).start(); 50 | //在大白上等待 51 | new Thread(new W(o2):: run).start(); 52 | new Thread(new W(o2):: run).start(); 53 | new Thread(new W(o2):: run).start(); 54 | new Thread(new W(o2):: run).start(); 55 | //通知小白上的 56 | new Thread(new N(o1):: run2).start(); 57 | //通知大白上的 58 | new Thread(new N(o2):: run2).start(); 59 | } 60 | 61 | static class O { 62 | String name; 63 | O(String name) { 64 | this.name = name; 65 | } 66 | } 67 | 68 | static class W { 69 | O o; 70 | W(O o) { 71 | this.o = o; 72 | } 73 | 74 | void run() { 75 | sleep(1); 76 | synchronized(o) { 77 | println("当前线程(%d)在对象(%s)上等待", Thread.currentThread().getId(), o.name); 78 | try { 79 | o.wait(); 80 | } catch (InterruptedException e) { 81 | e.printStackTrace(); 82 | } 83 | } 84 | println("当前线程(%d)在对象(%s)上因被通知而醒来", Thread.currentThread().getId(), o.name); 85 | } 86 | 87 | void run2() { 88 | sleep(1); 89 | int n = random(5, 10); 90 | synchronized(o) { 91 | println("当前线程(%d)在对象(%s)上等待[%d]秒", Thread.currentThread().getId(), o.name, n); 92 | try { 93 | o.wait(n * 1000); 94 | } catch (InterruptedException e) { 95 | e.printStackTrace(); 96 | } 97 | } 98 | println("当前线程(%d)在对象(%s)上因等待超过[%d]秒导致超时而自动醒来", Thread.currentThread().getId(), o.name, n); 99 | } 100 | } 101 | 102 | static class N { 103 | O o; 104 | N(O o) { 105 | this.o = o; 106 | } 107 | 108 | void run() { 109 | sleep(6); 110 | synchronized(o) { 111 | println("当前线程(%d)通知在对象(%s)上等待的其他单个线程", Thread.currentThread().getId(), o.name); 112 | o.notify(); 113 | } 114 | sleep(6); 115 | synchronized(o) { 116 | println("当前线程(%d)通知在对象(%s)上等待的其他单个线程", Thread.currentThread().getId(), o.name); 117 | o.notify(); 118 | } 119 | } 120 | 121 | void run2() { 122 | sleep(random(9, 19)); 123 | synchronized(o) { 124 | println("当前线程(%d)通知在对象(%s)上等待的其他所有线程", Thread.currentThread().getId(), o.name); 125 | o.notifyAll(); 126 | } 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/io/nio/NioServer.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.io.nio; 2 | 3 | import java.net.InetSocketAddress; 4 | import java.nio.ByteBuffer; 5 | import java.nio.channels.SelectionKey; 6 | import java.nio.channels.Selector; 7 | import java.nio.channels.ServerSocketChannel; 8 | import java.nio.channels.SocketChannel; 9 | import java.text.SimpleDateFormat; 10 | import java.util.Date; 11 | import java.util.Iterator; 12 | import java.util.Set; 13 | import java.util.concurrent.atomic.AtomicInteger; 14 | 15 | /** 16 | * @author lixinjie 17 | * @since 2019-05-07 18 | */ 19 | public class NioServer { 20 | 21 | static int clientCount = 0; 22 | static AtomicInteger counter = new AtomicInteger(0); 23 | static SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); 24 | 25 | public static void main(String[] args) { 26 | try { 27 | Selector selector = Selector.open(); 28 | ServerSocketChannel ssc = ServerSocketChannel.open(); 29 | ssc.configureBlocking(false); 30 | ssc.register(selector, SelectionKey.OP_ACCEPT); 31 | ssc.bind(new InetSocketAddress("localhost", 8080)); 32 | while (true) { 33 | selector.select(); 34 | Set keys = selector.selectedKeys(); 35 | Iterator iterator = keys.iterator(); 36 | while (iterator.hasNext()) { 37 | SelectionKey key = iterator.next(); 38 | iterator.remove(); 39 | if (key.isAcceptable()) { 40 | ServerSocketChannel ssc1 = (ServerSocketChannel)key.channel(); 41 | SocketChannel sc = null; 42 | while ((sc = ssc1.accept()) != null) { 43 | sc.configureBlocking(false); 44 | sc.register(selector, SelectionKey.OP_READ); 45 | InetSocketAddress rsa = (InetSocketAddress)sc.socket().getRemoteSocketAddress(); 46 | System.out.println(time() + "->" + rsa.getHostName() + ":" + rsa.getPort() + "->" + Thread.currentThread().getId() + ":" + (++clientCount)); 47 | } 48 | } else if (key.isReadable()) { 49 | //先将“读”从感兴趣操作移出,待把数据从通道中读完后,再把“读”添加到感兴趣操作中 50 | //否则,该通道会一直被选出来 51 | key.interestOps(key.interestOps() & (~ SelectionKey.OP_READ)); 52 | processWithNewThread((SocketChannel)key.channel(), key); 53 | } 54 | } 55 | } 56 | } catch (Exception e) { 57 | e.printStackTrace(); 58 | } 59 | } 60 | 61 | static void processWithNewThread(SocketChannel sc, SelectionKey key) { 62 | Runnable run = () -> { 63 | counter.incrementAndGet(); 64 | try { 65 | String result = readBytes(sc); 66 | //把“读”加进去 67 | key.interestOps(key.interestOps() | SelectionKey.OP_READ); 68 | System.out.println(time() + "->" + result + "->" + Thread.currentThread().getId() + ":" + counter.get()); 69 | sc.close(); 70 | } catch (Exception e) { 71 | e.printStackTrace(); 72 | } 73 | counter.decrementAndGet(); 74 | }; 75 | new Thread(run).start(); 76 | } 77 | 78 | static String readBytes(SocketChannel sc) throws Exception { 79 | long start = 0; 80 | int total = 0; 81 | int count = 0; 82 | ByteBuffer bb = ByteBuffer.allocate(1024); 83 | //开始读数据的时间 84 | long begin = System.currentTimeMillis(); 85 | while ((count = sc.read(bb)) > -1) { 86 | if (start < 1) { 87 | //第一次读到数据的时间 88 | start = System.currentTimeMillis(); 89 | } 90 | total += count; 91 | bb.clear(); 92 | } 93 | //读完数据的时间 94 | long end = System.currentTimeMillis(); 95 | return "wait=" + (start - begin) + "ms,read=" + (end - start) + "ms,total=" + total + "bs"; 96 | } 97 | 98 | static String time() { 99 | return sdf.format(new Date()); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/thread/sync/Synchronized.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.thread.sync; 2 | 3 | import static org.cnt.java.utils.Methods.*; 4 | 5 | /** 6 | * @author lixinjie 7 | * @since 2019-06-08 8 | */ 9 | public class Synchronized { 10 | 11 | boolean testThis(Synchronized sync) { 12 | return this == sync; 13 | } 14 | 15 | public static void main(String[] args) { 16 | Synchronized sync = new Synchronized(); 17 | //this就是new出来的对象本身 18 | println(sync.testThis(sync)); 19 | //对象监视器 20 | //test1(); 21 | 22 | 23 | //对象不相同 24 | println(new Object() == new Object()); 25 | //但类型信息相同 26 | println(new Object().getClass() == new Object().getClass()); 27 | //对象类型信息的两种获取方式 28 | println(new Object().getClass() == Object.class); 29 | //因为一个类被JVM加载 一次,生成一个Class类型的对象,表明类本身的信息,或称元数据信息 30 | //Class类型的对象也有监视器 31 | //test2(); 32 | 33 | //synchronized关键字用于获取对象的监视器 34 | //编译后对应于JVM的两条指令: 35 | //monitorenter/monitorexit 36 | //进入监视器/退出监视器 37 | //每次只有一个线程可以拥有一个对象的监视器 38 | //当线程即将进入等待时,会释放掉该对象的监视器 39 | //以便让其他线程获取这个对象的监视器,在适合的时候来通知自己 40 | } 41 | 42 | static void test1() { 43 | SyncA syncA = new SyncA(); 44 | SyncB syncB = new SyncB(syncA); 45 | new Thread(syncA::methodA).start(); 46 | new Thread(syncA::methodB).start(); 47 | new Thread(syncB::methodC).start(); 48 | } 49 | 50 | static class SyncA { 51 | 52 | public synchronized void methodA() { 53 | println3("enter into SyncA.methodA"); 54 | println("sleep..."); 55 | sleep(5); 56 | println3("drop out SyncA.methodA"); 57 | } 58 | 59 | public void methodB() { 60 | synchronized(this) { 61 | println3("enter into SyncA.methodB"); 62 | println("sleep..."); 63 | sleep(5); 64 | println3("drop out SyncA.methodB"); 65 | } 66 | } 67 | } 68 | 69 | static class SyncB { 70 | 71 | private SyncA syncA; 72 | 73 | public SyncB(SyncA syncA) { 74 | this.syncA = syncA; 75 | } 76 | 77 | public void methodC() { 78 | synchronized(syncA) { 79 | println3("enter into SyncB.methodC"); 80 | println("sleep..."); 81 | sleep(5); 82 | println3("drop out SyncB.methodC"); 83 | } 84 | } 85 | } 86 | 87 | //============================================ 88 | 89 | @SuppressWarnings("unchecked") 90 | static void test2() { 91 | new Thread(SyncC::methodA).start(); 92 | new Thread(SyncC::methodB).start(); 93 | new Thread(new SyncD(SyncC.class)::methodC).start(); 94 | new Thread(new SyncD((Class)new SyncC().getClass())::methodD).start(); 95 | } 96 | 97 | static class SyncC { 98 | 99 | public static synchronized void methodA() { 100 | println3("enter into SyncC.methodA"); 101 | println("sleep..."); 102 | sleep(5); 103 | println3("drop out SyncC.methodA"); 104 | } 105 | 106 | public static void methodB() { 107 | synchronized(SyncC.class) { 108 | println3("enter into SyncC.methodB"); 109 | println("sleep..."); 110 | sleep(5); 111 | println3("drop out SyncC.methodB"); 112 | } 113 | } 114 | } 115 | 116 | static class SyncD { 117 | 118 | private Class syncClass; 119 | 120 | public SyncD(Class syncClass) { 121 | this.syncClass = syncClass; 122 | } 123 | 124 | public void methodC() { 125 | synchronized(syncClass) { 126 | println3("enter into SyncD.methodC"); 127 | println("sleep..."); 128 | sleep(5); 129 | println3("drop out SyncD.methodC"); 130 | } 131 | } 132 | 133 | public void methodD() { 134 | synchronized(syncClass) { 135 | println3("enter into SyncD.methodD"); 136 | println("sleep..."); 137 | sleep(5); 138 | println3("drop out SyncD.methodD"); 139 | } 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/thread/thre/Thre.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.thread.thre; 2 | 3 | import static org.cnt.java.utils.Methods.*; 4 | 5 | /** 6 | * @author lixinjie 7 | * @since 2019-06-09 8 | */ 9 | public class Thre { 10 | 11 | public static void main(String[] args) { 12 | //test1(); 13 | //test2(); 14 | //test3(); 15 | test4(); 16 | } 17 | 18 | static void test1() { 19 | Thread t = new Thread(Interrupt::interrupt); 20 | t.start(); 21 | sleep(2); 22 | println2("主线程id=%d去中断线程tid=%d", Thread.currentThread().getId(), t.getId()); 23 | t.interrupt(); 24 | //sleep(2); 25 | } 26 | 27 | static void test2() { 28 | Thread t = new Thread(Interrupt::interrupt2); 29 | t.start(); 30 | sleep(2); 31 | println2("主线程id=%d去中断线程tid=%d", Thread.currentThread().getId(), t.getId()); 32 | t.interrupt(); 33 | //sleep(2); 34 | } 35 | 36 | static void test3() { 37 | Thread t = new Thread(Interrupt::interrupt3); 38 | t.start(); 39 | sleep(2); 40 | println2("主线程id=%d去中断线程tid=%d", Thread.currentThread().getId(), t.getId()); 41 | t.interrupt(); 42 | //sleep(2); 43 | } 44 | 45 | static void test4() { 46 | Thread t = new Thread(Interrupt::interrupt4); 47 | t.start(); 48 | sleep(2); 49 | println2("主线程id=%d去中断线程tid=%d", Thread.currentThread().getId(), t.getId()); 50 | t.interrupt(); 51 | //sleep(2); 52 | } 53 | 54 | static class Interrupt { 55 | 56 | static void interrupt() { 57 | Thread t = Thread.currentThread(); 58 | println2("线程tid=%d开始运行。。。", t.getId()); 59 | while(true) { 60 | if (t.isInterrupted()) { 61 | println2("线程tid=%d被中断", t.getId()); 62 | //该方法只返回当前中断状态,但不会清除中断状态 63 | println2("t.isInterrupted() is %s", t.isInterrupted()); 64 | println2("t.isInterrupted() is %s", t.isInterrupted()); 65 | //该方法返回当前中断状态并会清除中断状态 66 | println2("Thread.interrupted() is %s", Thread.interrupted()); 67 | //状态已清除 68 | println2("Thread.interrupted() is %s", Thread.interrupted()); 69 | //状态已清除 70 | println2("t.isInterrupted() is %s", t.isInterrupted()); 71 | //退出 72 | break; 73 | } 74 | } 75 | } 76 | 77 | static void interrupt2() { 78 | Thread t = Thread.currentThread(); 79 | try { 80 | println2("线程tid=%d开始睡眠。。。", t.getId()); 81 | Thread.sleep(10000); 82 | } catch (InterruptedException e) { 83 | e.printStackTrace(); 84 | println2("线程tid=%d在睡眠中被中断,且收到中断异常", t.getId()); 85 | //中断状态已经被清除(因为都已经有异常了,状态也就没必要了) 86 | println2("t.isInterrupted() is %s", t.isInterrupted()); 87 | } 88 | } 89 | 90 | static void interrupt3() { 91 | //因为是测试,所以就把监视器对象定义在方法里了 92 | Object object = new Object(); 93 | Thread t = Thread.currentThread(); 94 | try { 95 | println2("线程tid=%d开始等待。。。", t.getId()); 96 | synchronized(object) { 97 | object.wait(); 98 | } 99 | } catch (InterruptedException e) { 100 | e.printStackTrace(); 101 | println2("线程tid=%d在等待中被中断,且收到中断异常", t.getId()); 102 | //中断状态已经被清除(因为都已经有异常了,状态也就没必要了) 103 | println2("t.isInterrupted() is %s", t.isInterrupted()); 104 | } 105 | } 106 | 107 | static void interrupt4() { 108 | //启动一个线程,作为被等待的对象 109 | Thread wt = new Thread(() -> sleep(4)); 110 | wt.start(); 111 | 112 | Thread t = Thread.currentThread(); 113 | try { 114 | println2("线程tid=%d开始等待线程wtid=%d结束。。。", t.getId(), wt.getId()); 115 | //这里没有使用synchronized关键字获取监视器 116 | //因为join方法本身就是synchronized的, 117 | //因此监视器就是wt这个线程本身了 118 | wt.join(); 119 | } catch (InterruptedException e) { 120 | e.printStackTrace(); 121 | println2("线程tid=%d在等待线程wtid=%d结束过程中被中断,且收到中断异常", t.getId(), wt.getId()); 122 | //中断状态已经被清除(因为都已经有异常了,状态也就没必要了) 123 | println2("t.isInterrupted() is %s", t.isInterrupted()); 124 | } 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/thread/basic/ThreadOp.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.thread.basic; 2 | 3 | import static org.cnt.java.utils.Methods.doingLongTime; 4 | import static org.cnt.java.utils.Methods.println; 5 | import static org.cnt.java.utils.Methods.sleep; 6 | import static org.cnt.java.utils.Methods.sleep2; 7 | 8 | import java.time.format.DateTimeFormatter; 9 | 10 | /** 11 | * @author lixinjie 12 | * @since 2019-05-20 13 | */ 14 | public class ThreadOp { 15 | 16 | static DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm:ss"); 17 | 18 | public static void main(String[] args) throws Exception { 19 | stopByInterrupt(); 20 | synchronized (ThreadOp.class) { 21 | ThreadOp.class.wait(); 22 | } 23 | } 24 | 25 | static void stopByInterrupt() { 26 | DRunnable dr = new DRunnable(); 27 | Thread t = new Thread(dr); 28 | t.start(); 29 | sleep(2); 30 | t.interrupt(); 31 | } 32 | 33 | static class DRunnable implements Runnable { 34 | 35 | @Override 36 | public void run() { 37 | println("进入暂停。。。"); 38 | try { 39 | sleep2(5); 40 | } catch (InterruptedException e) { 41 | println("收到中断异常。。。"); 42 | println("做一些相关处理。。。"); 43 | } 44 | println("继续执行或选择退出。。。"); 45 | } 46 | 47 | } 48 | 49 | static void jqByJoin() { 50 | CRunnable cr = new CRunnable(); 51 | Thread t = new Thread(cr); 52 | t.start(); 53 | sleep(1); 54 | try { 55 | t.join(); 56 | } catch (InterruptedException e) { 57 | e.printStackTrace(); 58 | } 59 | println("终于轮到我了"); 60 | } 61 | 62 | static class CRunnable implements Runnable { 63 | 64 | @Override 65 | public void run() { 66 | println("进入不可暂停区域 1。。。"); 67 | doingLongTime(5); 68 | println("退出不可暂停区域 1。。。"); 69 | } 70 | 71 | } 72 | 73 | static void pause2Flag() { 74 | B2Runnable br = new B2Runnable(); 75 | new Thread(br).start(); 76 | br.tellToPauseAWhile(5); 77 | } 78 | 79 | static class B2Runnable implements Runnable { 80 | 81 | volatile boolean pause; 82 | 83 | volatile int timeout; 84 | 85 | void tellToPauseAWhile(int second) { 86 | pause = true; 87 | timeout = second * 1000; 88 | } 89 | 90 | @Override 91 | public void run() { 92 | println("进入不可暂停区域 1。。。"); 93 | doingLongTime(5); 94 | println("退出不可暂停区域 1。。。"); 95 | println("检测标志pause = %s", String.valueOf(pause)); 96 | if (pause) { 97 | println("暂停执行"); 98 | try { 99 | synchronized (this) { 100 | this.wait(timeout); 101 | } 102 | } catch (InterruptedException e) { 103 | e.printStackTrace(); 104 | } 105 | println("恢复执行"); 106 | } 107 | println("进入不可暂停区域 2。。。"); 108 | doingLongTime(5); 109 | println("退出不可暂停区域 2。。。"); 110 | } 111 | 112 | } 113 | 114 | static void pauseByFlag() { 115 | BRunnable br = new BRunnable(); 116 | new Thread(br).start(); 117 | br.tellToPause(); 118 | sleep(8); 119 | br.tellToResume(); 120 | } 121 | 122 | static class BRunnable implements Runnable { 123 | 124 | volatile boolean pause; 125 | 126 | void tellToPause() { 127 | pause = true; 128 | } 129 | 130 | void tellToResume() { 131 | synchronized (this) { 132 | this.notify(); 133 | } 134 | } 135 | 136 | @Override 137 | public void run() { 138 | println("进入不可暂停区域 1。。。"); 139 | doingLongTime(5); 140 | println("退出不可暂停区域 1。。。"); 141 | println("检测标志pause = %s", String.valueOf(pause)); 142 | if (pause) { 143 | println("暂停执行"); 144 | try { 145 | synchronized (this) { 146 | this.wait(); 147 | } 148 | } catch (InterruptedException e) { 149 | e.printStackTrace(); 150 | } 151 | println("恢复执行"); 152 | } 153 | println("进入不可暂停区域 2。。。"); 154 | doingLongTime(5); 155 | println("退出不可暂停区域 2。。。"); 156 | } 157 | 158 | } 159 | 160 | static void stopByFlag() { 161 | ARunnable ar = new ARunnable(); 162 | new Thread(ar).start(); 163 | ar.tellToStop(); 164 | } 165 | 166 | static class ARunnable implements Runnable { 167 | 168 | volatile boolean stop; 169 | 170 | void tellToStop() { 171 | stop = true; 172 | } 173 | 174 | @Override 175 | public void run() { 176 | println("进入不可停止区域 1。。。"); 177 | doingLongTime(5); 178 | println("退出不可停止区域 1。。。"); 179 | println("检测标志stop = %s", String.valueOf(stop)); 180 | if (stop) { 181 | println("停止执行"); 182 | return; 183 | } 184 | println("进入不可停止区域 2。。。"); 185 | doingLongTime(5); 186 | println("退出不可停止区域 2。。。"); 187 | } 188 | 189 | } 190 | 191 | } 192 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/generic/ListCvCtv.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.generic; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @author lixinjie 8 | * @since 2018-07-09 9 | */ 10 | public class ListCvCtv { 11 | 12 | static class Fruit {} 13 | static class Apple extends Fruit {} 14 | static class Orange extends Fruit {} 15 | static class Banana extends Fruit {} 16 | static class Peach extends Fruit {} 17 | 18 | static class YTApple extends Apple {} 19 | static class AKSApple extends Apple {} 20 | 21 | static void test1() { 22 | List alist = new ArrayList<>(); 23 | List olist = new ArrayList<>(); 24 | List blist = new ArrayList<>(); 25 | List plist = new ArrayList<>(); 26 | // List flist; 27 | // flist = alist; 28 | // flist = olist; 29 | // flist = (List)blist; 30 | // flist = (List)plist; 31 | List flist; 32 | flist = alist; 33 | flist = olist; 34 | flist = blist; 35 | flist = plist; 36 | } 37 | 38 | static void test2() { 39 | List alist = new ArrayList<>(); 40 | alist.add(new Apple()); 41 | alist.add(new YTApple()); 42 | alist.add(new AKSApple()); 43 | 44 | List flist; 45 | flist = alist; 46 | Fruit f0 = flist.get(0); 47 | Fruit f1 = flist.get(1); 48 | Fruit f2 = flist.get(2); 49 | System.out.println(f0); 50 | System.out.println(f1); 51 | System.out.println(f2); 52 | System.out.println("--------------------------"); 53 | for (Fruit f : flist) { 54 | System.out.println(f); 55 | } 56 | System.out.println("--------------------------"); 57 | flist.forEach(System.out::println); 58 | //读出数据没问题 59 | //实际存储的是Fruit的子类,读出时声明的类型是Fruit,其实是子类到父类的(自动)向上转型 60 | 61 | // flist.add(new Fruit()); 62 | // flist.add(new Apple()); 63 | // flist.add(new Orange()); 64 | // flist.add(new Banana()); 65 | // flist.add(new Peach()); 66 | //写入数据不可以 67 | //? extends Fruit表示的不是一个范围(无论什么水果),而是一种确切类型(具体某种水果) 68 | //底层是Fruit的一个子类,具体是哪个子类不知道,无法添加 69 | //这里底层List其实是Apple啊(理论上编译器可以推断出来),为什么添加Apple也不行,泛型参数在运行时被擦除了 70 | } 71 | 72 | static void test3() { 73 | List list = new ArrayList<>(); 74 | list.add("编程新说"); 75 | list.add(456789); 76 | //底层List持有的Object是所有类的父类,添加的都是它的子类 77 | List alist; 78 | List olist = new ArrayList<>(); 79 | List slist = new ArrayList<>(); 80 | List flist = new ArrayList<>(); 81 | List alist1 = new ArrayList<>(); 82 | List ytalist = new ArrayList<>(); 83 | alist = olist; 84 | alist = flist; 85 | alist = alist1; 86 | //alist = slist; 87 | //alist = (List)ytalist; 88 | alist.add(new Apple()); 89 | alist.add(new YTApple()); 90 | alist.add(new AKSApple()); 91 | //alist.add(new Fruit()); 92 | //写入数据没问题 93 | //写入的数据是Apple及Apple的子类,底层存储的类型实际是Apple及Apple的父类,其实还是子类到父类的(自动)向上转型 94 | Object o1 = alist.get(0); 95 | Object o2 = alist.get(1); 96 | Object o3 = alist.get(2); 97 | System.out.println(o1); 98 | System.out.println(o2); 99 | System.out.println(o3); 100 | System.out.println("--------------------------"); 101 | // for (Apple f : alist) { 102 | // 103 | // } 104 | // for (Fruit f : alist) { 105 | // 106 | // } 107 | for (Object f : alist) { 108 | System.out.println(f); 109 | } 110 | System.out.println("--------------------------"); 111 | alist.forEach(System.out::println); 112 | //读出数据没问题,只是类型都是Object 113 | //底层存储的类型实际是Apple及Apple的父类,它的父类可能有多个,编译器不知道是哪个,所以按顶级父类Object来推断 114 | } 115 | 116 | static void test4() { 117 | List flist = new ArrayList<>(); 118 | // flist.add(new Fruit()); 119 | // flist.add(new Apple()); 120 | // flist.add(new Orange()); 121 | // flist.add(new Banana()); 122 | // flist.add(new Peach()); 123 | //底层在运行时是支持的,被擦出到Object,只是编译器在编译时进行了限制,这正是泛型的目的,让问题尽早暴露出来 124 | ((List)(Object)flist).add(new Fruit()); 125 | ((List)(Object)flist).add(new Apple()); 126 | ((List)(Object)flist).add(new Orange()); 127 | ((List)(Object)flist).add(new Banana()); 128 | ((List)(Object)flist).add(new Peach()); 129 | ((List)(Object)flist).add("李新杰"); 130 | ((List)(Object)flist).add(123456); 131 | ((List)(Object)flist).add(new Object()); 132 | 133 | flist.forEach((Object f) -> System.out.println(f)); 134 | } 135 | 136 | static void test5() { 137 | List fread = new ArrayList<>(); 138 | List fwrite = new ArrayList<>(); 139 | test6(fread, fwrite); 140 | test7(fread, fwrite); 141 | List aread = new ArrayList<>(); 142 | List awrite = new ArrayList<>(); 143 | test7(aread, awrite); 144 | } 145 | 146 | /** 147 | * ? extends Fruit和? super Fruit都表示某种具体类型 148 | * extends表示输入,相当于入参,协变 149 | * super表示输出,相当于出参,逆变 150 | */ 151 | static void test6(List readFrom, List writeTo) { 152 | for (Fruit f : readFrom) { 153 | writeTo.add(f); 154 | } 155 | } 156 | 157 | static void test7(List readFrom, List writeTo) { 158 | for (T f : readFrom) { 159 | writeTo.add(f); 160 | } 161 | } 162 | 163 | 164 | public static void main(String[] args) { 165 | //test2(); 166 | //test3(); 167 | //test4(); 168 | } 169 | 170 | } 171 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/reflect/method/MainTest.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.reflect.method; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.Method; 5 | 6 | import org.cnt.java.utils.Log; 7 | 8 | /** 9 | * @author lixinjie 10 | * @since 2019-09-11 11 | */ 12 | public class MainTest { 13 | 14 | public static void main(String[] args) throws Exception { 15 | test1(); 16 | test2(); 17 | test3(); 18 | 19 | Log.log("\r\n---------------------------------\r\n"); 20 | 21 | test4(); 22 | test5(); 23 | 24 | Log.log("\r\n---------------------------------\r\n"); 25 | 26 | test6(); 27 | test7(); 28 | test8(); 29 | test9(); 30 | 31 | Log.log("\r\n---------------------------------\r\n"); 32 | 33 | test10(); 34 | 35 | Log.log("\r\n---------------------------------\r\n"); 36 | 37 | test11(); 38 | 39 | Log.log("\r\n---------------------------------\r\n"); 40 | 41 | test12(); 42 | test13(); 43 | test14(); 44 | } 45 | 46 | //公共方法 47 | static void test1() throws Exception { 48 | Method pm1 = Parent.class.getDeclaredMethod("m1"); 49 | Method cm1 = Child.class.getDeclaredMethod("m1"); 50 | Log.log(pm1); 51 | Log.log(cm1); 52 | Log.log("pm1 == cm1 -> {}", pm1 == cm1); 53 | Log.log("pm1.equals(cm1) -> {}", pm1.equals(cm1)); 54 | 55 | Parent p = new Parent(); 56 | Child c = new Child(); 57 | Log.log(pm1.invoke(p));//Parent.m1 58 | Log.log(pm1.invoke(c));//Child.m1 59 | 60 | //Log.log(cm1.invoke(p)); 61 | Log.log(cm1.invoke(c));//Child.m1 62 | } 63 | 64 | //受保护方法 65 | static void test2() throws Exception { 66 | Method pm2 = Parent.class.getDeclaredMethod("m2"); 67 | Method cm2 = Child.class.getDeclaredMethod("m2"); 68 | Log.log(pm2); 69 | Log.log(cm2); 70 | Log.log("pm2 == cm2 -> {}", pm2 == cm2); 71 | Log.log("pm2.equals(cm2) -> {}", pm2.equals(cm2)); 72 | 73 | Parent p = new Parent(); 74 | Child c = new Child(); 75 | Log.log(pm2.invoke(p));//Parent.m2 76 | Log.log(pm2.invoke(c));//Child.m2 77 | 78 | //Log.log(cm2.invoke(p)); 79 | Log.log(cm2.invoke(c));//Child.m2 80 | } 81 | 82 | //私有方法 83 | static void test3() throws Exception { 84 | Method pm3 = Parent.class.getDeclaredMethod("m3"); 85 | Method cm3 = Child.class.getDeclaredMethod("m3"); 86 | Log.log(pm3); 87 | Log.log(cm3); 88 | Log.log("pm3 == cm3 -> {}", pm3 == cm3); 89 | Log.log("pm3.equals(cm3) -> {}", pm3.equals(cm3)); 90 | 91 | Parent p = new Parent(); 92 | Child c = new Child(); 93 | pm3.setAccessible(true); 94 | cm3.setAccessible(true); 95 | 96 | Log.log(pm3.invoke(p));//Parent.m3 97 | Log.log(pm3.invoke(c));//Parent.m3 98 | 99 | //Log.log(cm3.invoke(p)); 100 | Log.log(cm3.invoke(c));//Child.m3 101 | } 102 | 103 | //抽象公共方法 104 | static void test4() throws Exception { 105 | Method pm1 = Parent2.class.getDeclaredMethod("m1"); 106 | Method cm1 = Child2.class.getDeclaredMethod("m1"); 107 | Log.log(pm1); 108 | Log.log(cm1); 109 | Log.log("pm1 == cm1 -> {}", pm1 == cm1); 110 | Log.log("pm1.equals(cm1) -> {}", pm1.equals(cm1)); 111 | 112 | Child2 c2 = new Child2(); 113 | 114 | Log.log(pm1.invoke(c2));//Child2.m1 115 | Log.log(cm1.invoke(c2));//Child2.m1 116 | } 117 | 118 | //抽象受保护方法 119 | static void test5() throws Exception { 120 | Method pm2 = Parent2.class.getDeclaredMethod("m2"); 121 | Method cm2 = Child2.class.getDeclaredMethod("m2"); 122 | Log.log(pm2); 123 | Log.log(cm2); 124 | Log.log("pm2 == cm2 -> {}", pm2 == cm2); 125 | Log.log("pm2.equals(cm2) -> {}", pm2.equals(cm2)); 126 | 127 | Child2 c2 = new Child2(); 128 | 129 | Log.log(cm2.invoke(c2));//Child2.m2 130 | Log.log(pm2.invoke(c2));//Child2.m2 131 | } 132 | 133 | //接口抽象方法 134 | static void test6() throws Exception { 135 | Method im1 = Inter.class.getDeclaredMethod("m1"); 136 | Method cm1 = Impl.class.getDeclaredMethod("m1"); 137 | Log.log(im1); 138 | Log.log(cm1); 139 | Log.log("im1 == cm1 -> {}", im1 == cm1); 140 | Log.log("im1.equals(cm1) -> {}", im1.equals(cm1)); 141 | 142 | Impl c = new Impl(); 143 | 144 | Log.log(im1.invoke(c));//Impl.m1 145 | Log.log(cm1.invoke(c));//Impl.m1 146 | } 147 | 148 | //接口默认方法,被重新实现 149 | static void test7() throws Exception { 150 | Method im2 = Inter.class.getDeclaredMethod("m2"); 151 | Method cm2 = Impl.class.getDeclaredMethod("m2"); 152 | Log.log(im2); 153 | Log.log(cm2); 154 | Log.log("im2 == cm2 -> {}", im2 == cm2); 155 | Log.log("im2.equals(cm2) -> {}", im2.equals(cm2)); 156 | 157 | Impl c = new Impl(); 158 | 159 | Log.log(im2.invoke(c));//Impl.m2 160 | Log.log(cm2.invoke(c));//Impl.m2 161 | } 162 | 163 | //接口默认方法,没有被重新实现,等于直接继承 164 | static void test8() throws Exception { 165 | Method im3 = Inter.class.getDeclaredMethod("m3"); 166 | //Method cm3 = Impl.class.getDeclaredMethod("m3"); 167 | Method cm3 = Impl.class.getMethod("m3"); 168 | Log.log(im3); 169 | Log.log(cm3); 170 | Log.log("im3 == cm3 -> {}", im3 == cm3); 171 | Log.log("im3.equals(cm3) -> {}", im3.equals(cm3));//true 172 | 173 | Impl c = new Impl(); 174 | 175 | Log.log(im3.invoke(c));//Inter.m3 176 | Log.log(cm3.invoke(c));//Inter.m3 177 | } 178 | 179 | //接口静态方法,无法被继承 180 | static void test9() throws Exception { 181 | Method im4 = Inter.class.getDeclaredMethod("m4"); 182 | //Method cm4 = Impl.class.getDeclaredMethod("m4"); 183 | //Method cm4 = Impl.class.getMethod("m4"); 184 | Log.log(im4); 185 | //Log.log(cm4); 186 | //Log.log(im4 == cm4); 187 | //Log.log(im4.equals(cm4)); 188 | 189 | Impl c = new Impl(); 190 | 191 | //静态方法,无需对象,所以参数随意 192 | Log.log(im4.invoke(c)); 193 | Log.log(im4.invoke(null)); 194 | Log.log(im4.invoke(new Object())); 195 | Log.log(im4.invoke(new String())); 196 | //Log.log(cm4.invoke(c)); 197 | 198 | //直接使用接口调用 199 | Log.log(Inter.m4()); 200 | 201 | //不能通过实现类调用接口的静态方法 202 | //Log.log(Impl.m4()); 203 | } 204 | 205 | //类的静态方法 206 | static void test10() throws Exception { 207 | Method cm5 = Impl.class.getDeclaredMethod("m5"); 208 | Method c2m5 = Impl2.class.getMethod("m5"); 209 | Log.log(cm5); 210 | Log.log(c2m5); 211 | Log.log("cm5 == c2m5 -> {}", cm5 == c2m5); 212 | Log.log("cm5.equals(c2m5) -> {}", cm5.equals(c2m5));//true 213 | 214 | Log.log(cm5.invoke(null)); 215 | Log.log(c2m5.invoke(null)); 216 | 217 | Log.log(Impl.m5()); 218 | //子类可以直接调用父类的静态方法 219 | Log.log(Impl2.m5()); 220 | } 221 | 222 | static void test11() throws Exception { 223 | Method m1 = Object.class.getDeclaredMethod("toString"); 224 | Method m2 = Object.class.getDeclaredMethod("toString"); 225 | //Method对象每次返回的都不是同一个,即不相同 226 | Log.log("m1 == m2 -> {}", m1 == m2);//false 227 | //但是它们相等 228 | Log.log("m1.equals(m2) -> {}", m1.equals(m2));//true 229 | } 230 | 231 | //公共字段 232 | static void test12() throws Exception { 233 | Field pf1 = Parent3.class.getDeclaredField("f1"); 234 | Field cf1 = Child3.class.getDeclaredField("f1"); 235 | Log.log(pf1); 236 | Log.log(cf1); 237 | Log.log("pf1.equals(cf1) -> {}", pf1.equals(cf1)); 238 | Parent3 p = new Parent3(); 239 | Child3 c = new Child3(); 240 | Log.log(pf1.get(p));//Parent3.f1 241 | Log.log(pf1.get(c));//Parent3.f1 242 | 243 | //Log.log(cf1.get(p)); 244 | Log.log(cf1.get(c));//Child3.f1 245 | } 246 | 247 | //受保护字段 248 | static void test13() throws Exception { 249 | Field pf2 = Parent3.class.getDeclaredField("f2"); 250 | Field cf2 = Child3.class.getDeclaredField("f2"); 251 | Log.log(pf2); 252 | Log.log(cf2); 253 | Log.log("pf2.equals(cf2) -> {}", pf2.equals(cf2)); 254 | Parent3 p = new Parent3(); 255 | Child3 c = new Child3(); 256 | Log.log(pf2.get(p));//Parent3.f2 257 | Log.log(pf2.get(c));//Parent3.f2 258 | 259 | //Log.log(cf2.get(p)); 260 | Log.log(cf2.get(c));//Child3.f2 261 | } 262 | 263 | //私有字段 264 | static void test14() throws Exception { 265 | Field pf3 = Parent3.class.getDeclaredField("f3"); 266 | Field cf3 = Child3.class.getDeclaredField("f3"); 267 | Log.log(pf3); 268 | Log.log(cf3); 269 | Log.log("pf3.equals(cf3) -> {}", pf3.equals(cf3)); 270 | Parent3 p = new Parent3(); 271 | Child3 c = new Child3(); 272 | 273 | pf3.setAccessible(true); 274 | cf3.setAccessible(true); 275 | Log.log(pf3.get(p));//Parent3.f3 276 | Log.log(pf3.get(c));//Parent3.f3 277 | 278 | //Log.log(cf3.get(p)); 279 | Log.log(cf3.get(c));//Child3.f3 280 | } 281 | } 282 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/digit/Digit.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.digit; 2 | 3 | /** 4 | * @author lixinjie 5 | * @since 2019-07-09 6 | */ 7 | public class Digit { 8 | 9 | public static void main(String[] args) { 10 | //binaryRepresent(); 11 | //binaryOperate(); 12 | //binaryShift(); 13 | //binaryStretch(); 14 | //digitSerDes(); 15 | unsignedDigit(); 16 | } 17 | 18 | //最高位是符号位,0表示正数,1表示负数。 19 | //0既不是正数也不是负数,计算机把它当作正数。 20 | //把一个数当作正数,它的二进制形式就是原码。 21 | //把原码中的0变为1、1变为0,此时称为反码。 22 | //反码加1就是补码。 23 | static void binaryRepresent() { 24 | log(binary(0)); 25 | //00000000 26 | 27 | log(binary(1)); 28 | //00000001 29 | log(binary(-1)); 30 | //11111111 31 | 32 | log(binary(2)); 33 | //00000010 34 | log(binary(-2)); 35 | //11111110 36 | 37 | log(binary(5)); 38 | //00000101 39 | log(binary(-5)); 40 | //11111011 41 | 42 | log(binary(Byte.MAX_VALUE)); 43 | //01111111 44 | log(binary(-Byte.MAX_VALUE)); 45 | //10000001 46 | 47 | log(binary(Byte.MIN_VALUE)); 48 | //10000000 49 | 50 | //从9转换-9(取反再加1) 51 | log(binary(~9 + 1)); 52 | log(binary(-9)); 53 | } 54 | 55 | //二进制的与/或/非/异或 56 | //与(and),&,1 & 1 -> 1,其余都是0 57 | //或(or),|,0 | 0 -> 0,其余都是1 58 | //非(not),~,也称取反,0变成1、1变成0 59 | //异或(xor),^,0 ^ 1 -> 1,1 ^ 0 -> 1,其余都是0 60 | static void binaryOperate() { 61 | log(binary(0b00001010 & 0b00001111)); 62 | //00001010 63 | log(binary(0b00001010 | 0b00001111)); 64 | //00001111 65 | log(binary(~0b00001010)); 66 | //11110101 67 | log(binary(0b00001010 ^ 0b00001111)); 68 | //00000101 69 | } 70 | 71 | //二进制的左移/右移 72 | //左移(<<)时,左边丢弃(符号位照样丢弃),右边补0,左移一位相当于乘2,二位相当于乘4,以此类推。 73 | //移完后,最高位是0为正数,是1为负数。正数和负数左移时都遵从这个规律。 74 | //当左移一个周期时,回到原点。即相当于不移。超过一个周期后,把周期部分除掉,移动剩下的。 75 | 76 | //右移(>>)时,右边丢弃,正数左边补0,负数左边补1,右移一位相当于除2,二位相当于除4,以此类推。 77 | //在四舍五入时,正数选择舍,负数选择入。 78 | //正数右移从都丢弃完开始往后都是0,因为二进制都是0,直到到达一个周期时,回到原点。相当于不移。 79 | //超过一个周期后,把周期部分除掉,移动剩下的。 80 | //负数右移从都丢弃完开始往后都是-1,因为二进制都是1,直到到达一个周期时,回到原点。相当于不移。 81 | //超过一个周期后,把周期部分除掉,移动剩下的。 82 | 83 | //无符号右移(>>>)时,右边丢弃,正数和负数左边都补0。 84 | //因此对于正数来说和右移(>>)没有什么差别。 85 | //对于负数来说会变成正数,就是使用原来的补码形式,丢弃右边后当作正数来计算。 86 | 87 | //为什么没有无符号左移? 88 | //因为左移时,在右边补0,而符号位在最左边,右边补的东西是影响不到它的。 89 | static void binaryShift() { 90 | log(5); 91 | //5 92 | log(5 << 1); 93 | //10 94 | log(5 << 2); 95 | //20 96 | log(5 << 3); 97 | //40 98 | log(binary(5)); 99 | //101 100 | log(binary(5 << 1)); 101 | //1010 102 | log(binary(5 << 2)); 103 | //10100 104 | log(binary(5 << 3)); 105 | //101000 106 | 107 | log(-5); 108 | //-5 109 | log(-5 << 1); 110 | //-10 111 | log(-5 << 2); 112 | //-20 113 | log(-5 << 3); 114 | //-40 115 | log(binary(-5)); 116 | //011 117 | log(binary(-5 << 1)); 118 | //0110 119 | log(binary(-5 << 2)); 120 | //01100 121 | log(binary(-5 << 3)); 122 | //01100 123 | 124 | log(""); 125 | 126 | log(5); 127 | //5 128 | log(5 << 29); 129 | //-1610612736 130 | log(5 << 30); 131 | //1073741824 132 | log(5 << 31); 133 | //-2147483648 134 | log(5 << 32); 135 | //5 136 | log(5 << 33); 137 | //10 138 | log(binary(5)); 139 | //101 140 | log(binary(5 << 29)); 141 | //10100000000000000000000000000000 142 | log(binary(5 << 30)); 143 | //01000000000000000000000000000000 144 | log(binary(5 << 31)); 145 | //10000000000000000000000000000000 146 | 147 | log(-5); 148 | //-5 149 | log(-5 << 29); 150 | //1610612736 151 | log(-5 << 30); 152 | //-1073741824 153 | log(-5 << 31); 154 | //-2147483648 155 | log(-5 << 32); 156 | //-5 157 | log(-5 << 33); 158 | //-10 159 | log(binary(-5)); 160 | //011 161 | log(binary(-5 << 29)); 162 | //01100000000000000000000000000000 163 | log(binary(-5 << 30)); 164 | //11000000000000000000000000000000 165 | log(binary(-5 << 31)); 166 | //10000000000000000000000000000000 167 | 168 | log("------------------------------"); 169 | 170 | log(99); 171 | //99 172 | log(99 >> 1); 173 | //49 174 | log(99 >> 2); 175 | //24 176 | log(99 >> 3); 177 | //12 178 | log(binary(99)); 179 | //1100011 180 | log(binary(99 >> 1)); 181 | //110001 182 | log(binary(99 >> 2)); 183 | //11000 184 | log(binary(99 >> 3)); 185 | //1100 186 | 187 | log(-99); 188 | //-99 189 | log(-99 >> 1); 190 | //-50 191 | log(-99 >> 2); 192 | //-25 193 | log(-99 >> 3); 194 | //-13 195 | log(binary(-99)); 196 | //0011101 197 | log(binary(-99 >> 1)); 198 | //1001110 199 | log(binary(-99 >> 2)); 200 | //1100111 201 | log(binary(-99 >> 3)); 202 | //1110011 203 | 204 | log(""); 205 | 206 | log(99); 207 | //99 208 | log(99 >> 6); 209 | //1 210 | log(99 >> 7); 211 | //0 212 | log(99 >> 8); 213 | //0 214 | log(99 >> 9); 215 | //0 216 | log(99 >> 31); 217 | //0 218 | log(99 >> 32); 219 | //99 220 | log(99 >> 33); 221 | //49 222 | log(binary(99)); 223 | //1100011 224 | log(binary(99 >> 6)); 225 | //1 226 | log(binary(99 >> 7)); 227 | //0 228 | log(binary(99 >> 8)); 229 | //0 230 | log(binary(99 >> 9)); 231 | //0 232 | log(binary(99 >> 31)); 233 | //0 234 | log(binary(99 >> 32)); 235 | //1100011 236 | log(binary(99 >> 33)); 237 | //110001 238 | 239 | log(-99); 240 | //-99 241 | log(-99 >> 6); 242 | //-2 243 | log(-99 >> 7); 244 | //-1 245 | log(-99 >> 8); 246 | //-1 247 | log(-99 >> 9); 248 | //-1 249 | log(-99 >> 31); 250 | //-1 251 | log(-99 >> 32); 252 | //-99 253 | log(-99 >> 33); 254 | //-50 255 | log(binary(-99)); 256 | //0011101 257 | log(binary(-99 >> 6)); 258 | //1111110 259 | log(binary(-99 >> 7)); 260 | //1111111 261 | log(binary(-99 >> 8)); 262 | //1111111 263 | log(binary(-99 >> 9)); 264 | //1111111 265 | log(binary(-99 >> 31)); 266 | //1111111 267 | log(binary(-99 >> 32)); 268 | //0011101 269 | log(binary(-99 >> 33)); 270 | //1001110 271 | 272 | log("------------------------------"); 273 | 274 | log(99); 275 | //99 276 | log(99 >>> 1); 277 | //49 278 | log(99 >>> 2); 279 | //24 280 | log(99 >>> 7); 281 | //0 282 | log(99 >>> 8); 283 | //0 284 | log(99 >>> 30); 285 | //0 286 | log(99 >>> 31); 287 | //0 288 | log(99 >>> 32); 289 | //99 290 | log(99 >>> 33); 291 | //49 292 | log(binary(99)); 293 | //1100011 294 | log(binary(99 >>> 1)); 295 | //110001 296 | log(binary(99 >>> 2)); 297 | //11000 298 | log(binary(99 >>> 7)); 299 | //0 300 | log(binary(99 >>> 8)); 301 | //0 302 | log(binary(99 >>> 30)); 303 | //0 304 | log(binary(99 >>> 31)); 305 | //0 306 | log(binary(99 >>> 32)); 307 | //1100011 308 | log(binary(99 >>> 33)); 309 | //110001 310 | 311 | log(-99); 312 | //-99 313 | log(-99 >>> 1); 314 | //2147483598 315 | log(-99 >>> 2); 316 | //1073741799 317 | log(-99 >>> 7); 318 | //33554431 319 | log(-99 >>> 8); 320 | //16777215 321 | log(-99 >>> 30); 322 | //3 323 | log(-99 >>> 31); 324 | //1 325 | log(-99 >>> 32); 326 | //-99 327 | log(-99 >>> 33); 328 | //2147483598 329 | log(binary(-99)); 330 | //11111111111111111111111110011101 331 | log(binary(-99 >>> 1)); 332 | //01111111111111111111111111001110 333 | log(binary(-99 >>> 2)); 334 | //00111111111111111111111111100111 335 | log(binary(-99 >>> 7)); 336 | //00000001111111111111111111111111 337 | log(binary(-99 >>> 8)); 338 | //00000000111111111111111111111111 339 | log(binary(-99 >>> 30)); 340 | //00000000000000000000000000000011 341 | log(binary(-99 >>> 31)); 342 | //00000000000000000000000000000001 343 | log(binary(-99 >>> 32)); 344 | //11111111111111111111111110011101 345 | log(binary(-99 >>> 33)); 346 | //01111111111111111111111111001110 347 | } 348 | 349 | //二进制的伸/缩 350 | 351 | //伸,把一个字节伸长为两个字节,需要填充高位字节。 352 | //此时符号和数值大小保持不变。 353 | //正数符号位是0,伸长时高字节填充0。 354 | //负数符号位是1,伸长时高字节填充1。 355 | 356 | //缩,把两个字节压缩为一个字节,需要截断高位字节。 357 | //此时符号和数值大小都可能发生改变。 358 | //如果压缩后的字节仍能放得下这个数,则符号和数值大小保持不变。 359 | //正数和负数都遵从这个规律。 360 | //就是如果正数的高位字节全是0,负数的高位字节全是1,截断高位字节不会对数造成影响。 361 | //如果压缩后的字节放不下这个数,则数值大小一定改变。 362 | //符号是否改变取决于低位字节的最高位与原高位字节的最高位是否一样。 363 | //如果一样则符号不变,反之则符号改变。 364 | //就是如果正数的高位字节不全是0,负数的高位字节不全是1,截断高位字节会对数造成影响。 365 | //且数值大小一定改变,符号则由新符号位和原符号位来决定。 366 | static void binaryStretch() { 367 | byte b = 5; 368 | short s = b; 369 | log(b); 370 | //5 371 | log(s); 372 | //5 373 | log(binary(b)); 374 | //00000101 375 | log(binary(s)); 376 | //0000000000000101 377 | 378 | b = -5; 379 | s = b; 380 | log(b); 381 | //-5 382 | log(s); 383 | //-5 384 | log(binary(b)); 385 | //11111011 386 | log(binary(s)); 387 | //1111111111111011 388 | 389 | log(""); 390 | 391 | s = 127; 392 | b = (byte)s; 393 | log(s); 394 | //127 395 | log(b); 396 | //127 397 | log(binary(s)); 398 | //0000000001111111 399 | log(binary(b)); 400 | //01111111 401 | 402 | s = -127; 403 | b = (byte)s; 404 | log(s); 405 | //-127 406 | log(b); 407 | //-127 408 | log(binary(s)); 409 | //1111111110000001 410 | log(binary(b)); 411 | //10000001 412 | 413 | log(""); 414 | 415 | s = 261; 416 | b = (byte)s; 417 | log(s); 418 | //261 419 | log(b); 420 | //5 421 | log(binary(s)); 422 | //0000000100000101 423 | log(binary(b)); 424 | //00000101 425 | 426 | s = -261; 427 | b = (byte)s; 428 | log(s); 429 | //-261 430 | log(b); 431 | //-5 432 | log(binary(s)); 433 | //1111111011111011 434 | log(binary(b)); 435 | //11111011 436 | 437 | log(""); 438 | 439 | s = 389; 440 | b = (byte)s; 441 | log(s); 442 | //389 443 | log(b); 444 | //-123 445 | log(binary(s)); 446 | //0000000110000101 447 | log(binary(b)); 448 | //10000101 449 | 450 | s = -389; 451 | b = (byte)s; 452 | log(s); 453 | //-389 454 | log(b); 455 | //123 456 | log(binary(s)); 457 | //1111111001111011 458 | log(binary(b)); 459 | //01111011 460 | } 461 | 462 | //数字的序列化/反序列化 463 | //序列化,把数字变成字节数组,如把一个整型拆分成四个字节 464 | //将需要获取的字节无符号右移至最低位 465 | //与0xff执行与操作将剩余所有高位字节清空 466 | //强制转换成byte类型,会只保留最低位字节,高位字节被丢弃 467 | //反序列化,把字节数组变成数字,如把四个字节合成一个整型 468 | //把最高位字节左移至最高位,它是带有符号位的 469 | //把剩余的字节与0xff执行与操作,作用有两个 470 | //一是把单个字节伸长 471 | //二是清空因伸长而产生的高位字节 472 | //然后再把这些字节左移到适合的位置 473 | //最后再把这些字节加起来 474 | //重要说明: 475 | //在序列化时,可以不用无符号右移,而用右移 476 | //对于正数没有区别,左边都是补0 477 | //对于负数,一个左边补0,一个左边补1, 478 | //左边补什么其实无所谓,因为向byte强制转换时都被丢弃 479 | //也可以不与0xff执行与操作来清空高位字节 480 | //清不清空其实无所谓,因为向byte强制转换时都被丢弃 481 | //所以序列化的关键就是把需要摘取的字节移至最低位 482 | //通过强制转换为byte类型,丢弃高位而只保留最低位 483 | //在反序列化时,首先要做的就是把一个 byte伸长 484 | //如果byte的最高位是0,伸长时高位字节填充的都是0 485 | //如果byte的最高位是1,伸长时高位字节填充的都是1 486 | //对于第一个字节,其实它是带符号的,所以不用处理 487 | //对于后续的字节,它的符号位是要作为数值来对待的 488 | //所以如果符号位是0的话,高位字节填充的是0,不用处理 489 | //如果符号位是1的话,高位字节填充的是1,此时需要与0xff 490 | //执行与操作,把高位字节填充的这些1全部清空为0 491 | //不至于影响到后续的左移操作 492 | //所以反序列化的关键就是把单个字节放到最低位 493 | //然后左移到适合的位置 494 | //最后再把这些字节加起来构成一个数字 495 | static void digitSerDes() { 496 | byte[] bs = new byte[4]; 497 | int i = 2043453625; 498 | log(i); 499 | //2043453625 500 | log(binary(i)); 501 | //01111001110011001010000010111001 502 | bs[0] = (byte)((i >>> 24) & 0xff); 503 | log(binary(bs[0])); 504 | //01111001 505 | bs[1] = (byte)((i >>> 16) & 0xff); 506 | log(binary(bs[1])); 507 | //11001100 508 | bs[2] = (byte)((i >>> 8) & 0xff); 509 | log(binary(bs[2])); 510 | //10100000 511 | bs[3] = (byte)((i >>> 0) & 0xff); 512 | log(binary(bs[3])); 513 | //10111001 514 | log(""); 515 | log(binary(bs[0] << 24)); 516 | //01111001000000000000000000000000 517 | log(binary((bs[1] & 0xff) << 16)); 518 | //00000000110011000000000000000000 519 | log(binary((bs[2] & 0xff) << 8)); 520 | //00000000000000001010000000000000 521 | log(binary((bs[3] & 0xff) << 0)); 522 | //00000000000000000000000010111001 523 | log((bs[0] << 24) + ((bs[1] & 0xff) << 16) + ((bs[2] & 0xff) << 8) + ((bs[3] & 0xff) << 0)); 524 | //2043453625 525 | log((bs[0] << 24) | ((bs[1] & 0xff) << 16) | ((bs[2] & 0xff) << 8) | ((bs[3] & 0xff) << 0)); 526 | //2043453625 527 | 528 | log("---------------------------------"); 529 | 530 | bs = new byte[4]; 531 | i = -2043453625; 532 | log(i); 533 | //-2043453625 534 | log(binary(i)); 535 | //10000110001100110101111101000111 536 | bs[0] = (byte)((i >>> 24) & 0xff); 537 | log(binary(bs[0])); 538 | //10000110 539 | bs[1] = (byte)((i >>> 16) & 0xff); 540 | log(binary(bs[1])); 541 | //00110011 542 | bs[2] = (byte)((i >>> 8) & 0xff); 543 | log(binary(bs[2])); 544 | //01011111 545 | bs[3] = (byte)((i >>> 0) & 0xff); 546 | log(binary(bs[3])); 547 | //01000111 548 | log(""); 549 | log(binary(bs[0] << 24)); 550 | //10000110000000000000000000000000 551 | log(binary((bs[1] & 0xff) << 16)); 552 | //00000000001100110000000000000000 553 | log(binary((bs[2] & 0xff) << 8)); 554 | //00000000000000000101111100000000 555 | log(binary((bs[3] & 0xff) << 0)); 556 | //00000000000000000000000001000111 557 | log((bs[0] << 24) + ((bs[1] & 0xff) << 16) + ((bs[2] & 0xff) << 8) + ((bs[3] & 0xff) << 0)); 558 | //-2043453625 559 | log((bs[0] << 24) | ((bs[1] & 0xff) << 16) | ((bs[2] & 0xff) << 8) | ((bs[3] & 0xff) << 0)); 560 | //-2043453625 561 | } 562 | 563 | //无符号数,即最高位不是符号位而是数值 564 | //Java的数字都是带符号的,所以无符号需要模拟实现 565 | //因为同一个类型作为无符号数时的范围会大于作为 566 | //有符号数时的范围,因此会用更长的类型存放短类型 567 | //的无符号数。 568 | //byte类型作为有符号数时范围是-128到127,作为无符 569 | //号数时范围时0到255,所以至少需要用short类型来 570 | //存放 571 | //做法就是把有符号数的字节进行伸长,把因伸长而 572 | //产生的高位字节用0填充,因为短类型的无符号数, 573 | //在范围上对应于长类型的有符号正数,实际上也是 574 | //这样来模拟的。 575 | static void unsignedDigit() { 576 | byte b = -5; 577 | log(b); 578 | //-5 579 | log(binary(b)); 580 | //11111011 581 | short s = (short)(b & 0xff); 582 | log(s); 583 | //251 584 | log(binary(s)); 585 | //0000000011111011 586 | 587 | log(""); 588 | 589 | b = -1; 590 | log(b); 591 | //-1 592 | log(binary(b)); 593 | //11111111 594 | s = (short)(b & 0xff); 595 | log(s); 596 | //255 597 | log(binary(s)); 598 | //0000000011111111 599 | 600 | log(""); 601 | 602 | b = -128; 603 | log(b); 604 | //-128 605 | log(binary(b)); 606 | //10000000 607 | s = (short)(b & 0xff); 608 | log(s); 609 | //128 610 | log(binary(s)); 611 | //0000000010000000 612 | 613 | log(""); 614 | 615 | s = -30567; 616 | log(s); 617 | //-30567 618 | log(binary(s)); 619 | //1000100010011001 620 | int i = s & 0xffff; 621 | log(i); 622 | //34969 623 | log(binary(i)); 624 | //00000000000000001000100010011001 625 | } 626 | 627 | static void log(Object o) { 628 | System.out.println(o); 629 | } 630 | 631 | static String binary(int i) { 632 | return Integer.toBinaryString(i); 633 | } 634 | } 635 | -------------------------------------------------------------------------------- /src/main/java/org/cnt/java/annotation/typ/c/CTest.java: -------------------------------------------------------------------------------- 1 | package org.cnt.java.annotation.typ.c; 2 | 3 | import java.lang.reflect.AnnotatedElement; 4 | import java.util.Arrays; 5 | import java.util.stream.Stream; 6 | 7 | import org.cnt.java.annotation.ann.c.AnnC13; 8 | import org.cnt.java.annotation.ann.c.AnnC23; 9 | import org.cnt.java.annotation.ann.c.AnnC33; 10 | import org.cnt.java.annotation.ann.c.AnnC43; 11 | import org.cnt.java.annotation.ann.r.AnnR11; 12 | import org.cnt.java.annotation.ann.r.AnnR12; 13 | import org.cnt.java.annotation.ann.r.AnnRC11; 14 | import org.cnt.java.annotation.ann.r.AnnRC12; 15 | import org.cnt.java.utils.Logger; 16 | 17 | /** 18 | * @author lixinjie 19 | * @since 2019-07-25 20 | */ 21 | public class CTest { 22 | 23 | static Logger log = Logger.getLogger(); 24 | 25 | public static void main(String[] args) { 26 | log.info("------------------------{}-------------------------", "test1()"); 27 | test1(); 28 | log.info("------------------------{}-------------------------", "test2()"); 29 | test2(); 30 | log.info("------------------------{}-------------------------", "test3()"); 31 | test3(); 32 | log.info("------------------------{}-------------------------", "test4()"); 33 | test4(); 34 | log.info("------------------------{}-------------------------", "test5()"); 35 | test5(); 36 | log.info("------------------------{}-------------------------", "test6()"); 37 | test6(); 38 | log.info("------------------------{}-------------------------", "test7()"); 39 | test7(); 40 | } 41 | 42 | static void test1() { 43 | //getAnnotations() 44 | 45 | AnnotatedElement ae1 = C1.class; 46 | log.info("[C1] getAnnotations()=["); 47 | Stream.of(ae1.getAnnotations()).forEach(ann -> log.info("{}", ann)); 48 | log.info("]"); 49 | //output:输出C1上标的三个注解 50 | 51 | AnnotatedElement ae2 = C2.class; 52 | log.info("[C2] getAnnotations()=["); 53 | Stream.of(ae2.getAnnotations()).forEach(ann -> log.info("{}", ann)); 54 | log.info("]"); 55 | //output:输出C2上标的二个以及从C1继承的一个 56 | 57 | //result:此方法会考虑从父类上继承注解 58 | 59 | //note:只有标有@Inherited的注解才具有继承性 60 | //note:子类上的注解会重写父类上的同名注解 61 | 62 | //数组中注解的顺序是: 63 | //按照源码中注解标注的从上到下从左到右的顺序(其实符合自然的先后顺序) 64 | //如果考虑从父类继承的话,则父类更靠前。 65 | //子类上重写父类的那些注解,按父类的注解位置走,但是采用子类的注解实例。 66 | 67 | //下面是对可重复注解的测试 68 | //有两种写法: 69 | //1)把多个注解分散着直接标到类型上 70 | //2)把多个注解放到容器注解中,容器注解标到类型上 71 | 72 | AnnotatedElement ae11 = CR11.class; 73 | log.info("[CR11] getAnnotations()=["); 74 | Stream.of(ae11.getAnnotations()).forEach(ann -> log.info("{}", ann)); 75 | log.info("]"); 76 | //output:输出CR11上标的注解,发现都以容器的形式呈现 77 | 78 | AnnotatedElement ae21 = CR21.class; 79 | log.info("[CR21] getAnnotations()=["); 80 | Stream.of(ae21.getAnnotations()).forEach(ann -> log.info("{}", ann)); 81 | log.info("]"); 82 | //output:输出CR21的注解,发现全部继承CR11上的 83 | 84 | //result:可重复注解也遵循继承规则 85 | 86 | AnnotatedElement ae22 = CR22.class; 87 | log.info("[CR22] getAnnotations()=["); 88 | Stream.of(ae22.getAnnotations()).forEach(ann -> log.info("{}", ann)); 89 | log.info("]"); 90 | //output:输出CR22的注解,主要测试对父类注解的重写,采用同形式重写 91 | //note:容器的形式可以重写父类容器形式,即使子类的容器是空的 92 | //note:分散的形式暂时不能重写父类分散的形式,可能是父类分散的有5个,子类只有1个 93 | // 结果是父类的5个被继承,以容器的形式,子类这1个也存在,以分散的形式 94 | 95 | AnnotatedElement ae23 = CR23.class; 96 | log.info("[CR23] getAnnotations()=["); 97 | Stream.of(ae23.getAnnotations()).forEach(ann -> log.info("{}", ann)); 98 | log.info("]"); 99 | //output:输出CR23的注解,主要测试对父类注解的重写,采用同形式重写 100 | //note:容器的形式可以重写父类容器形式 101 | //note:分散的形式此时可以重写父类分散的形式,可能是父类分散的有5个,子类现在已达到2个 102 | // 当分散的形式只有1个时,就以分散的形式存在,当达到2个时,就自动转换为容器形式 103 | // 父类是5个,所以是容器形式,子类现在达到2个,也变成了容器形式,都是容器,类型相同了,所以就重写了 104 | // 上个示例中,父类是容器形式,子类是分散形式,类型不相同,所以就没有重写,而是同时存在了 105 | 106 | AnnotatedElement ae31 = CR31.class; 107 | log.info("[CR31] getAnnotations()=["); 108 | Stream.of(ae31.getAnnotations()).forEach(ann -> log.info("{}", ann)); 109 | log.info("]"); 110 | //output:输出CR31的注解,主要验证分散形式只有1个时,不会转换为容器形式,至少达到2个时才会 111 | // 结果确实是这样的,因为从2个开始就是数组了,必须放入容器中才行,于是自动转换为容器了 112 | 113 | AnnotatedElement ae32 = CR32.class; 114 | log.info("[CR32] getAnnotations()=["); 115 | Stream.of(ae32.getAnnotations()).forEach(ann -> log.info("{}", ann)); 116 | log.info("]"); 117 | //output:输出CR32的注解,主要验证无论分散形式还是容器形式,只要形式相同就可以重写 118 | // 结果确实是这样的,分散形式可以,容器形式也可以,无论是直接标的容器,还是自动转换的容器 119 | 120 | AnnotatedElement ae33 = CR33.class; 121 | log.info("[CR33] getAnnotations()=["); 122 | Stream.of(ae33.getAnnotations()).forEach(ann -> log.info("{}", ann)); 123 | log.info("]"); 124 | //output:输出CR33的注解,主要验证无论分散形式还是容器形式,只要形式不相同就不可以重写 125 | // 结果确实是这样的 126 | 127 | //对于可重复注解: 128 | //1)标着分散形式,只有1个,以分散形式存在 129 | //2)标着分散形式,至少2个,自动转换为容器形式,已容器形式存在 130 | //3)标着容器形式,即使是空的,也只能以容器形式存在 131 | //子类继承父类重写注解时: 132 | //1)子类和父类注解形式必须相同才可以重写 133 | //2)子类分散形式重写父类分散形式 134 | //3)子类容器形式重写父类容器形式 135 | //4)子类分散父类容器、子类容器父类分散,则不会重写,而是继承下来同时存在 136 | } 137 | 138 | static void test2() { 139 | //getDeclaredAnnotations() 140 | 141 | AnnotatedElement ae1 = C1.class; 142 | log.info("[C1] getDeclaredAnnotations()=["); 143 | Stream.of(ae1.getDeclaredAnnotations()).forEach(ann -> log.info("{}", ann)); 144 | log.info("]"); 145 | //output:输出C1上标的三个注解 146 | 147 | AnnotatedElement ae2 = C2.class; 148 | log.info("[C2] getDeclaredAnnotations()=["); 149 | Stream.of(ae2.getDeclaredAnnotations()).forEach(ann -> log.info("{}", ann)); 150 | log.info("]"); 151 | //output:输出C2上标的二个 152 | 153 | //result:此方法不考虑从父类的继承,只关注本类上有的 154 | 155 | //下面是对可重复注解的测试 156 | 157 | AnnotatedElement ae11 = CR11.class; 158 | log.info("[CR11] getDeclaredAnnotations()=["); 159 | Stream.of(ae11.getDeclaredAnnotations()).forEach(ann -> log.info("{}", ann)); 160 | log.info("]"); 161 | //output:输出CR11上标的注解,发现都以容器的形式呈现 162 | 163 | AnnotatedElement ae21 = CR21.class; 164 | log.info("[CR21] getDeclaredAnnotations()=["); 165 | Stream.of(ae21.getDeclaredAnnotations()).forEach(ann -> log.info("{}", ann)); 166 | log.info("]"); 167 | //output:输出CR21的注解,发现是空的,因为不考虑继承 168 | 169 | //result:可重复注解也遵循不继承规则 170 | 171 | AnnotatedElement ae22 = CR22.class; 172 | log.info("[CR22] getDeclaredAnnotations()=["); 173 | Stream.of(ae22.getDeclaredAnnotations()).forEach(ann -> log.info("{}", ann)); 174 | log.info("]"); 175 | //output:输出CR22的注解,不考虑继承 176 | 177 | AnnotatedElement ae23 = CR23.class; 178 | log.info("[CR23] getDeclaredAnnotations()=["); 179 | Stream.of(ae23.getDeclaredAnnotations()).forEach(ann -> log.info("{}", ann)); 180 | log.info("]"); 181 | //output:输出CR23的注解,不考虑继承 182 | 183 | AnnotatedElement ae31 = CR31.class; 184 | log.info("[CR31] getDeclaredAnnotations()=["); 185 | Stream.of(ae31.getDeclaredAnnotations()).forEach(ann -> log.info("{}", ann)); 186 | log.info("]"); 187 | //output:输出CR31的注解,不考虑继承 188 | 189 | AnnotatedElement ae32 = CR32.class; 190 | log.info("[CR32] getDeclaredAnnotations()=["); 191 | Stream.of(ae32.getDeclaredAnnotations()).forEach(ann -> log.info("{}", ann)); 192 | log.info("]"); 193 | //output:输出CR32的注解,不考虑继承 194 | 195 | AnnotatedElement ae33 = CR33.class; 196 | log.info("[CR33] getDeclaredAnnotations()=["); 197 | Stream.of(ae33.getDeclaredAnnotations()).forEach(ann -> log.info("{}", ann)); 198 | log.info("]"); 199 | //output:输出CR33的注解,不考虑继承 200 | 201 | //对于可重复注解: 202 | //1)标着分散形式,只有1个,以分散形式存在 203 | //2)标着分散形式,至少2个,自动转换为容器形式,已容器形式存在 204 | //3)标着容器形式,即使是空的,也只能以容器形式存在 205 | //子类不继承父类注解,不用考虑重写 206 | } 207 | 208 | static void test3() { 209 | //getAnnotation(Class) 210 | 211 | AnnotatedElement ae1 = C1.class; 212 | log.info("getAnnotation(AnnC13.class)={}", ae1.getAnnotation(AnnC13.class)); 213 | log.info("getAnnotation(AnnC33.class)={}", ae1.getAnnotation(AnnC33.class)); 214 | log.info("getAnnotation(AnnC43.class)={}", ae1.getAnnotation(AnnC43.class)); 215 | //output:只可以获取getAnnotations()方法返回的注解 216 | 217 | AnnotatedElement ae2 = C2.class; 218 | log.info("getAnnotation(AnnC23.class)={}", ae2.getAnnotation(AnnC23.class)); 219 | log.info("getAnnotation(AnnC33.class)={}", ae2.getAnnotation(AnnC33.class)); 220 | log.info("getAnnotation(AnnC43.class)={}", ae2.getAnnotation(AnnC43.class)); 221 | //output:只可以获取getAnnotations()方法返回的注解 222 | 223 | //result:此方法只可以获取getAnnotations()方法返回的注解 224 | 225 | //可重复注解 226 | AnnotatedElement ae11 = CR11.class; 227 | log.info("getAnnotation(AnnRC11.class)={}", ae11.getAnnotation(AnnRC11.class)); 228 | log.info("getAnnotation(AnnR11.class)={}", ae11.getAnnotation(AnnR11.class)); 229 | log.info("getAnnotation(AnnRC12.class)={}", ae11.getAnnotation(AnnRC12.class)); 230 | log.info("getAnnotation(AnnR12.class)={}", ae11.getAnnotation(AnnR12.class)); 231 | //output:只可以获取getAnnotations()方法返回的注解 232 | // 因为是容器形式,所以只能获取容器注解。分散的获取不到 233 | 234 | //可重复注解 235 | AnnotatedElement ae21 = CR21.class; 236 | log.info("getAnnotation(AnnRC11.class)={}", ae21.getAnnotation(AnnRC11.class)); 237 | log.info("getAnnotation(AnnR11.class)={}", ae21.getAnnotation(AnnR11.class)); 238 | log.info("getAnnotation(AnnRC12.class)={}", ae21.getAnnotation(AnnRC12.class)); 239 | log.info("getAnnotation(AnnR12.class)={}", ae21.getAnnotation(AnnR12.class)); 240 | //output:只可以获取getAnnotations()方法返回的注解 241 | // 子类继承父类,和上一个输出的一样 242 | 243 | //可重复注解 244 | AnnotatedElement ae31 = CR31.class; 245 | log.info("getAnnotation(AnnRC11.class)={}", ae31.getAnnotation(AnnRC11.class)); 246 | log.info("getAnnotation(AnnR11.class)={}", ae31.getAnnotation(AnnR11.class)); 247 | //output:只可以获取getAnnotations()方法返回的注解 248 | // 因为是分散形式,所以只能获取分散注解。容器的获取不到 249 | } 250 | 251 | static void test4() { 252 | //getDeclaredAnnotation(Class) 253 | 254 | AnnotatedElement ae1 = C1.class; 255 | log.info("getDeclaredAnnotation(AnnC13.class)={}", ae1.getDeclaredAnnotation(AnnC13.class)); 256 | log.info("getDeclaredAnnotation(AnnC33.class)={}", ae1.getDeclaredAnnotation(AnnC33.class)); 257 | log.info("getDeclaredAnnotation(AnnC43.class)={}", ae1.getDeclaredAnnotation(AnnC43.class)); 258 | //output:只可以获取getDeclaredAnnotations()方法返回的注解 259 | 260 | AnnotatedElement ae2 = C2.class; 261 | log.info("getDeclaredAnnotation(AnnC23.class)={}", ae2.getDeclaredAnnotation(AnnC23.class)); 262 | log.info("getDeclaredAnnotation(AnnC33.class)={}", ae2.getDeclaredAnnotation(AnnC33.class)); 263 | log.info("getDeclaredAnnotation(AnnC43.class)={}", ae2.getDeclaredAnnotation(AnnC43.class)); 264 | //output:只可以获取getDeclaredAnnotations()方法返回的注解 265 | 266 | //result:此方法只可以获取getDeclaredAnnotations()方法返回的注解 267 | 268 | //可重复注解 269 | AnnotatedElement ae11 = CR11.class; 270 | log.info("getDeclaredAnnotation(AnnRC11.class)={}", ae11.getDeclaredAnnotation(AnnRC11.class)); 271 | log.info("getDeclaredAnnotation(AnnR11.class)={}", ae11.getDeclaredAnnotation(AnnR11.class)); 272 | log.info("getDeclaredAnnotation(AnnRC12.class)={}", ae11.getDeclaredAnnotation(AnnRC12.class)); 273 | log.info("getDeclaredAnnotation(AnnR12.class)={}", ae11.getDeclaredAnnotation(AnnR12.class)); 274 | //output:只可以获取getDeclaredAnnotations()方法返回的注解 275 | // 因为是容器形式,所以只能获取容器注解。分散的获取不到 276 | 277 | //可重复注解 278 | AnnotatedElement ae21 = CR21.class; 279 | log.info("getDeclaredAnnotation(AnnRC11.class)={}", ae21.getDeclaredAnnotation(AnnRC11.class)); 280 | log.info("getDeclaredAnnotation(AnnR11.class)={}", ae21.getDeclaredAnnotation(AnnR11.class)); 281 | log.info("getDeclaredAnnotation(AnnRC12.class)={}", ae21.getDeclaredAnnotation(AnnRC12.class)); 282 | log.info("getDeclaredAnnotation(AnnR12.class)={}", ae21.getDeclaredAnnotation(AnnR12.class)); 283 | //output:只可以获取getDeclaredAnnotations()方法返回的注解 284 | // 因为不考虑从父类继承,所以全部都获取不到 285 | 286 | //可重复注解 287 | AnnotatedElement ae31 = CR31.class; 288 | log.info("getDeclaredAnnotation(AnnRC11.class)={}", ae31.getDeclaredAnnotation(AnnRC11.class)); 289 | log.info("getDeclaredAnnotation(AnnR11.class)={}", ae31.getDeclaredAnnotation(AnnR11.class)); 290 | //output:只可以获取getDeclaredAnnotations()方法返回的注解 291 | // 因为是分散形式,所以只能获取分散注解。容器的获取不到 292 | } 293 | 294 | static void test5() { 295 | //isAnnotationPresent(Class) 296 | 297 | AnnotatedElement ae1 = C1.class; 298 | log.info("isAnnotationPresent(AnnC13.class)={}", ae1.isAnnotationPresent(AnnC13.class)); 299 | log.info("isAnnotationPresent(AnnC33.class)={}", ae1.isAnnotationPresent(AnnC33.class)); 300 | log.info("isAnnotationPresent(AnnC43.class)={}", ae1.isAnnotationPresent(AnnC43.class)); 301 | //output:只可以获取getAnnotations()方法返回的注解 302 | 303 | AnnotatedElement ae2 = C2.class; 304 | log.info("isAnnotationPresent(AnnC23.class)={}", ae2.isAnnotationPresent(AnnC23.class)); 305 | log.info("isAnnotationPresent(AnnC33.class)={}", ae2.isAnnotationPresent(AnnC33.class)); 306 | log.info("isAnnotationPresent(AnnC43.class)={}", ae2.isAnnotationPresent(AnnC43.class)); 307 | //output:只可以获取getAnnotations()方法返回的注解 308 | 309 | //result:此方法只可以获取getAnnotations()方法返回的注解 310 | 311 | //可重复注解 312 | AnnotatedElement ae11 = CR11.class; 313 | log.info("isAnnotationPresent(AnnRC11.class)={}", ae11.isAnnotationPresent(AnnRC11.class)); 314 | log.info("isAnnotationPresent(AnnR11.class)={}", ae11.isAnnotationPresent(AnnR11.class)); 315 | log.info("isAnnotationPresent(AnnRC12.class)={}", ae11.isAnnotationPresent(AnnRC12.class)); 316 | log.info("isAnnotationPresent(AnnR12.class)={}", ae11.isAnnotationPresent(AnnR12.class)); 317 | //output:只可以获取getAnnotations()方法返回的注解 318 | // 因为是容器形式,所以只能获取容器注解。分散的获取不到 319 | 320 | //可重复注解 321 | AnnotatedElement ae21 = CR21.class; 322 | log.info("isAnnotationPresent(AnnRC11.class)={}", ae21.isAnnotationPresent(AnnRC11.class)); 323 | log.info("isAnnotationPresent(AnnR11.class)={}", ae21.isAnnotationPresent(AnnR11.class)); 324 | log.info("isAnnotationPresent(AnnRC12.class)={}", ae21.isAnnotationPresent(AnnRC12.class)); 325 | log.info("isAnnotationPresent(AnnR12.class)={}", ae21.isAnnotationPresent(AnnR12.class)); 326 | //output:只可以获取getAnnotations()方法返回的注解 327 | // 子类继承父类,和上一个输出的一样 328 | 329 | //可重复注解 330 | AnnotatedElement ae31 = CR31.class; 331 | log.info("isAnnotationPresent(AnnRC11.class)={}", ae31.isAnnotationPresent(AnnRC11.class)); 332 | log.info("isAnnotationPresent(AnnR11.class)={}", ae31.isAnnotationPresent(AnnR11.class)); 333 | //output:只可以获取getAnnotations()方法返回的注解 334 | // 因为是分散形式,所以只能获取分散注解。容器的获取不到 335 | } 336 | 337 | static void test6() { 338 | //getAnnotationsByType(Class) 339 | 340 | AnnotatedElement ae1 = C1.class; 341 | log.info("getAnnotationsByType(AnnC13.class)={}", Arrays.toString(ae1.getAnnotationsByType(AnnC13.class))); 342 | log.info("getAnnotationsByType(AnnC33.class)={}", Arrays.toString(ae1.getAnnotationsByType(AnnC33.class))); 343 | log.info("getAnnotationsByType(AnnC43.class)={}", Arrays.toString(ae1.getAnnotationsByType(AnnC43.class))); 344 | //output:只可以获取getAnnotations()方法返回的注解 345 | 346 | AnnotatedElement ae2 = C2.class; 347 | log.info("getAnnotationsByType(AnnC23.class)={}", Arrays.toString(ae2.getAnnotationsByType(AnnC23.class))); 348 | log.info("getAnnotationsByType(AnnC33.class)={}", Arrays.toString(ae2.getAnnotationsByType(AnnC33.class))); 349 | log.info("getAnnotationsByType(AnnC43.class)={}", Arrays.toString(ae2.getAnnotationsByType(AnnC43.class))); 350 | //output:只可以获取getAnnotations()方法返回的注解 351 | 352 | //result:此方法只可以获取getAnnotations()方法返回的注解 353 | 354 | //可重复注解 355 | AnnotatedElement ae11 = CR11.class; 356 | log.info("getAnnotationsByType(AnnRC11.class)={}", Arrays.toString(ae11.getAnnotationsByType(AnnRC11.class))); 357 | log.info("getAnnotationsByType(AnnR11.class)={}", Arrays.toString(ae11.getAnnotationsByType(AnnR11.class))); 358 | log.info("getAnnotationsByType(AnnRC12.class)={}", Arrays.toString(ae11.getAnnotationsByType(AnnRC12.class))); 359 | log.info("getAnnotationsByType(AnnR12.class)={}", Arrays.toString(ae11.getAnnotationsByType(AnnR12.class))); 360 | //output:只可以获取getAnnotations()方法返回的注解 361 | // 如果寻找分散形式,但不存在。则会寻找它的容器,找到的话则取出容器中的值返回,否则就是没找到 362 | 363 | //可重复注解 364 | AnnotatedElement ae21 = CR21.class; 365 | log.info("getAnnotationsByType(AnnRC11.class)={}", Arrays.toString(ae21.getAnnotationsByType(AnnRC11.class))); 366 | log.info("getAnnotationsByType(AnnR11.class)={}", Arrays.toString(ae21.getAnnotationsByType(AnnR11.class))); 367 | log.info("getAnnotationsByType(AnnRC12.class)={}", Arrays.toString(ae21.getAnnotationsByType(AnnRC12.class))); 368 | log.info("getAnnotationsByType(AnnR12.class)={}", Arrays.toString(ae21.getAnnotationsByType(AnnR12.class))); 369 | //output:只可以获取getAnnotations()方法返回的注解 370 | // 子类继承父类,和上一个输出的一样 371 | 372 | //可重复注解 373 | AnnotatedElement ae31 = CR31.class; 374 | log.info("getAnnotationsByType(AnnRC11.class)={}", Arrays.toString(ae31.getAnnotationsByType(AnnRC11.class))); 375 | log.info("getAnnotationsByType(AnnR11.class)={}", Arrays.toString(ae31.getAnnotationsByType(AnnR11.class))); 376 | //output:只可以获取getAnnotations()方法返回的注解 377 | // 如果寻找容器,但不存在,那就不存在了。 378 | 379 | //result:带ByType与不带的唯一区别是,当寻找可重复注解时,如不存在则尝试寻找它的容器,并从容器中获取该重复注解。 380 | // 如果容器也不存在,那就认为不存在了。 381 | } 382 | 383 | static void test7() { 384 | //getDeclaredAnnotationsByType(Class) 385 | 386 | AnnotatedElement ae1 = C1.class; 387 | log.info("getDeclaredAnnotationsByType(AnnC13.class)={}", Arrays.toString(ae1.getDeclaredAnnotationsByType(AnnC13.class))); 388 | log.info("getDeclaredAnnotationsByType(AnnC33.class)={}", Arrays.toString(ae1.getDeclaredAnnotationsByType(AnnC33.class))); 389 | log.info("getDeclaredAnnotationsByType(AnnC43.class)={}", Arrays.toString(ae1.getDeclaredAnnotationsByType(AnnC43.class))); 390 | //output:只可以获取getDeclaredAnnotations()方法返回的注解 391 | 392 | AnnotatedElement ae2 = C2.class; 393 | log.info("getDeclaredAnnotationsByType(AnnC23.class)={}", Arrays.toString(ae2.getDeclaredAnnotationsByType(AnnC23.class))); 394 | log.info("getDeclaredAnnotationsByType(AnnC33.class)={}", Arrays.toString(ae2.getDeclaredAnnotationsByType(AnnC33.class))); 395 | log.info("getDeclaredAnnotationsByType(AnnC43.class)={}", Arrays.toString(ae2.getDeclaredAnnotationsByType(AnnC43.class))); 396 | //output:只可以获取getDeclaredAnnotations()方法返回的注解 397 | 398 | //result:此方法只可以获取getDeclaredAnnotations()方法返回的注解 399 | 400 | //可重复注解 401 | AnnotatedElement ae11 = CR11.class; 402 | log.info("getDeclaredAnnotationsByType(AnnRC11.class)={}", Arrays.toString(ae11.getDeclaredAnnotationsByType(AnnRC11.class))); 403 | log.info("getDeclaredAnnotationsByType(AnnR11.class)={}", Arrays.toString(ae11.getDeclaredAnnotationsByType(AnnR11.class))); 404 | log.info("getDeclaredAnnotationsByType(AnnRC12.class)={}", Arrays.toString(ae11.getDeclaredAnnotationsByType(AnnRC12.class))); 405 | log.info("getDeclaredAnnotationsByType(AnnR12.class)={}", Arrays.toString(ae11.getDeclaredAnnotationsByType(AnnR12.class))); 406 | //output:只可以获取getDeclaredAnnotations()方法返回的注解 407 | // 如果寻找分散形式,但不存在。则会寻找它的容器,找到的话则取出容器中的值返回,否则就是没找到 408 | 409 | //可重复注解 410 | AnnotatedElement ae21 = CR21.class; 411 | log.info("getDeclaredAnnotationsByType(AnnRC11.class)={}", Arrays.toString(ae21.getDeclaredAnnotationsByType(AnnRC11.class))); 412 | log.info("getDeclaredAnnotationsByType(AnnR11.class)={}", Arrays.toString(ae21.getDeclaredAnnotationsByType(AnnR11.class))); 413 | log.info("getDeclaredAnnotationsByType(AnnRC12.class)={}", Arrays.toString(ae21.getDeclaredAnnotationsByType(AnnRC12.class))); 414 | log.info("getDeclaredAnnotationsByType(AnnR12.class)={}", Arrays.toString(ae21.getDeclaredAnnotationsByType(AnnR12.class))); 415 | //output:只可以获取getDeclaredAnnotations()方法返回的注解 416 | // 子类不继承父类,所以输出都是空 417 | 418 | //可重复注解 419 | AnnotatedElement ae31 = CR31.class; 420 | log.info("getDeclaredAnnotationsByType(AnnRC11.class)={}", Arrays.toString(ae31.getDeclaredAnnotationsByType(AnnRC11.class))); 421 | log.info("getDeclaredAnnotationsByType(AnnR11.class)={}", Arrays.toString(ae31.getDeclaredAnnotationsByType(AnnR11.class))); 422 | //output:只可以获取getDeclaredAnnotations()方法返回的注解 423 | // 如果直接寻找容器,但不存在,那就不存在了。 424 | 425 | //result:带ByType与不带的唯一区别是,当寻找可重复注解时,如不存在则尝试寻找它的容器,并从容器中获取该重复注解。 426 | // 如果容器也不存在,那就认为不存在了。 427 | } 428 | 429 | } 430 | --------------------------------------------------------------------------------