Java高级

抽象类和抽象方法

1.定义

随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。

类的设计应该保证父类和子类都能够共享特征。

有时候将一个父类设计的非常抽象,以至于他都没有具体的实例,这样的类叫做抽象类。

优势:不能被实例化

2.abstract修饰类:抽象类

抽象类不能实例化

抽象类中一定有构造器,便于子类实例化时调用(涉及:子类实例化的全过程)

开发中,都会提供抽象类的子类,让子类对象使用,完成相关操作。

3.abstract修饰方法:抽象方法

抽象方法只有方法的声明,没有方法体。

包含抽象方法的类,一定是一个抽象方法,然而,抽象类中可以没有抽象方法。

若子类重写类父类中的所有方法后,此子类方可实例化。

若子类没有重写父类中的所有方法抽象方法,

则此子类也是一个抽象类,需要使用abstract修饰该子类。

4.abstract关键字的注意事项

abstract不能用来修饰:属性、构造器等结构。

abstract不能用来修饰私有方法、静态方法、final修饰的方法。

接口

接口的特性:

  属性:需要public static final修饰

  方法:要求public abstract

  没有构造方法,也没有程序块

  接口不能创建对象,子类多实现接口来做事

  接口也是一种引用数据类型

  接口是完全抽象的。(抽象类是半抽象的)或者说,接口是特殊的抽象类。

接口和抽象类的相同点和不同点

可以实现多个接口,不能继承多个类

final关键字

  final可以声明类、属性、方法

  final标记的类不能被继承(final和abstract不能同时存在),没有子类

  final标记的基本数据类型不能被改变//public void func(final int i){i++;}会报错

  final标记的引用数据类型是可以改变其属性的(不改变引用数据类型的地址,不能new)//public void func(final Object o){o.i++;}

  final标记的方法不能被重写,可以重载

  final标记的标量是常量,一般public static final double Pi=3.14,常量可以被私有(goto 和 const在java中是关键字,但不过被使用,这种叫做保留关键字)

枚举

枚举指的是一组固定的常量组成的类型

类型安全:取值只能在涌现的范围内选择

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public enum Season {
    Spring("春天","春意盎然"),
    Summer("夏天","夏日炎炎"),
    ;
    private String seasonName;
    private String seasonDesc;
  
    Season(String seasonName, String seasonDesc) {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }
  
    public String getSeasonName() {
        return seasonName;
    }
  
    public void setSeasonName(String seasonName) {
        this.seasonName = seasonName;
    }
  
    public String getSeasonDesc() {
        return seasonDesc;
    }
  
    public void setSeasonDesc(String seasonDesc) {
        this.seasonDesc = seasonDesc;
    }
}

 

1
2
3
4
5
6
public class TestSeason {
    public static void main(String[] args) {
        Season spring = Season.Spring;
        System.out.println(spring.getSeasonName()+"---"+spring.getSeasonDesc());
    }
}

 

异常

谁调用,谁处理

异常处理的五个关键字

捕获异常:try/catch/finally

抛出异常:throw  可以手动抛出异常对象;例如throw new Exception("异常信息")

声明异常:throws  声明方法  可能要抛出的各种异常了,向上传递异常,直到Main函数  保证程序可以正常运行

returnType methodName(...) throws Exception{

  throw new Exception("异常信息");

}

运行时异常RuntimeException

Exception---------------------------------------------------------异常层次结构的根类

ArithmeticException--------------------------------------------算术错误情形,如 以零作为除数

ArrayIndexOutOfExceptionBoundsException------------数组下标越界

NullPointerException-------------------------------------------尝试访问null对象成员

NumberFormatException-------------------------------------数字格式转换异常,如 把"abc"转换成数字

检查异常CheckException:检查异常是程序员必须进行处理

何时需要自定义异常

当JDK中的异常不能满足程序需要的时候

自定义异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MyException extends Exception{//自定义异常
    private int errorCode;//异常编码
  
    public int getErrorCode() {
        return errorCode;
    }
  
    public void setErrorCode(int errorCode) {
        this.errorCode = errorCode;
    }
  
    public MyException() {
    }
  
    public MyException(int errorCode,String msg) {
        super(msg);
        this.errorCode = errorCode;
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void main(String[] args) {
        System.out.println("请输入1~3之间的任何一个数:");
        Scanner input = new Scanner(System.in);
        try{
            int num=input.nextInt();
            if (num==1){
                System.out.println("课程1");
            }else if (num==2){
                System.out.println("课程2");
            }else if(num==3){
                System.out.println("课程3");
            }else {
                System.out.println("输入错误,输入的数不在1~3之间");
            }
        }catch (Exception e){
            System.out.println("输出错误,发生异常");
        }finally {
            System.out.println("欢迎提出建议");
        }
    }

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Item07 {
    private int age;
    public void setAge(int age) throws MyException{
        if (age<=100&&0<=age){
            this.age=age;
        }else {
            throw new MyException(1001,"年龄必须在1到100岁之间");
        }
    }
    public static void main(String[] args) {
        Item07 item07 = new Item07();
        try {
            item07.setAge(101);
        } catch (MyException e) {
            System.out.println("异常编码:"+e.getErrorCode()+"异常信息:"+e.getMessage());
        }
    }
}

 

注解

内置的注解

Java 定义了一套注解,共有 7 个,3 个在 java.lang 中,剩下 4 个在 java.lang.annotation 中。

作用在代码的注解是

  • @Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。

  • @Deprecated - 标记过时方法。如果使用该方法,会报编译警告。

  • @SuppressWarnings - 指示编译器去忽略注解中声明的警告。

作用在其他注解的注解(或者说 元注解)是:

  • @Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。

  • @Documented - 标记这些注解是否包含在用户文档中。

  • @Target - 标记这个注解应该是哪种 Java 成员。

  • @Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)

从 Java 7 开始,额外添加了 3 个注解:

  • @SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。

  • @FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。

  • @Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。

自定义注解

1
2
3
4
5
6
7
8
9
10
11
12
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
  
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
  
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    int age() default 20;
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import java.lang.annotation.Annotation;
  
public class Person {
    @Deprecated
    private String name;
    @MyAnnotation(age = 16)
    private int age;
  
    public void sayHi(){
  
    }
  
    @MyAnnotation(age = 16)
    public void setAge(){
  
    }
  
    public void checkAge() throws NoSuchFieldException, NoSuchMethodException {
        //通过反射加载Person类,并获取名为"age"的属性下的所有注解
//        Annotation[] annotations = Person.class.getDeclaredField("age").getAnnotations();//getField("age").getAnnotations();
        Annotation[] annotations = Person.class.getMethod("setAge").getAnnotations();
        //遍历输出
        for (Annotation a : annotations) {
            if (a instanceof MyAnnotation){//找到自定义注解
                if (((MyAnnotation)a).age()<18){//读取注解中的年龄信息,并进行判断
                    System.out.println("未成年");
                }else {
                    System.out.println("具备选举权");
                }
            }
        }
    }
  
    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
        Person person = new Person();
        person.checkAge();
    }
}

 内部类

内部类与外部类的关系

1.成员内部类的创建需要依赖于外部类对象(成员方法必须用过对象调用),在没有外部类实例之前无法创建成员内部类对象

2.内部类与外部类相对独立,不是is a关系

3.私有属性的相互访问,内部类可以直接访问外部类,而外部类访问内部类需要内部类的对象来访问

4.创建内部类的语法

  在外部类内部创建内部类对象Inner inner = new Inner();

  在外部类外部创建内部类对象,外部类.内部类 inner=new Outer().new Inner();

5.在内部类内部使用隐藏的外部类对象,外部类类名.this

内部类的优势

内部类不受外部类是否继承各类,是多重继承的完美解决方案,是对JAVA单一继承的有益补充

内部类的分类

静态内部类

使用static修饰,类比静态方法,不需要外部类对象产生就内使用

不能访问外部类的成员域,只能访问静态域

创建语法

1.外部类内部:与成员内部类一样

2.外部了外部:Inner inner=new Outer.Inner();

非静态内部类

对外部完全隐藏,因此方法内部类不能用任何的访问修饰符

方法内部类没有访问形参,这个形参是可以在方法中随意修改的,一旦方法内部类中使用了形参,这个形参必须被声明为final

匿名内部类

1.必须继承一个抽象类或者实现一个接口

2.没有构造方法

反射

在编译时不确定哪个类被加载,而在程序运行时才加载、探知、使用

基于Class类

Class类是Java反射机制的起源和入口,每个类都有自己的Class对象,用于获取与类相关的各种信息,提供了获取信息的相关方法,Class类继承自Object类

优点

提高了Java程序的灵活性和扩展性,降低了耦合性

问题

可读性较差,反射会模糊程序内部逻辑

主要使用到的类

Class类---可获取类与类的成员信息

Field类---可访问类的属性

Method类---可调用类的方法

Constructor类---可调用类的构造方法

使用反射机制的一般步骤

1.通过反射加载类(三种方式)

1
2
3
4
5
6
7
//第一种:对象名.getClass();
Student student = new Student("jack", 10);
Class aClass=student.getClass();
//第二种:类名.class;
Class aClass = Student.class;
//第三种:Class.forName("加载类的所在路径")
Class aClass = Class.forName("com.cx.demo.Student");

2.通过反射创建对象(两种方式)

1
2
3
4
5
6
Class aClass = Class.forName("com.cx.demo.Student");
//1.调用无参数的构造方法
Student student =(Student) aClass.newInstance();//创建一个实例
//2.调用指定构造方法getDeclaredFields(指定构造方法对应参数的数据类型)
Constructor con = aClass.getDeclaredConstructor(String.class,int.class);
Student ton = (Student)con.newInstance("ton", 23);//创建一个实例

3.通过反射操作属性

1
2
3
4
5
6
7
8
9
Class clazz = Class.forName("com.cx.demo.Student");
Student stu = (Student) clazz.newInstance();//属性是对象的一部分
//getDeclaredFields():所有属性,包括私有的
Field[] declaredFields = clazz.getDeclaredFields();
//getDeclaredField("属性名"):指定属性
Field name = clazz.getDeclaredField("name");
//stu.setName设置属性值
name.setAccessible(true);//使得可以获取私有属性 如果是private属性,必须设置为true
name.set(stu,"张三");

4.通过反射动态执行方法

1
2
3
4
5
6
7
8
Class clazz = Class.forName("com.cx.demo.Student");
Student stu = (Student) clazz.newInstance();
//1.得到方法getDeclaredMethod("方法名",方法所带参数的数据类型)
Method show = clazz.getDeclaredMethod("show", String.class);
//2.动态调用方法invoke(所属对象,传入的参数)
show.invoke(stu,"反射太麻烦了");
//所有的方法,不包括过构造方法
Method[] declaredMethods = aClass.getDeclaredMethods();

 

几个常用的工具类

时间转换类

SimpleDateFormat

使用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
  
public class TestDate {
    //"2022-10-18"-->Date
    public static void main(String[] args) {
        String str = "2022-10-18";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = sdf.parse(str);//String--->Date
            System.out.println(date);
            String format = sdf.format(date);//Date---->String
            System.out.println(format);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

 工具类案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.text.SimpleDateFormat;
import java.util.Date;
  
public class DateUtil {
    //日期格式
    private static final String pattern="yyyy-MM-dd";
    private static final SimpleDateFormat sdf=new SimpleDateFormat(pattern);
    //将字符串转换成日期
    public static Date convertToDate(String str) throws Exception{
        Date date=null;
        date=sdf.parse(str);
        return date;
    }
    //将日期转换字符串
    public static String convertToString(Date date){
        String str=null;
        str=sdf.format(date);
        return str;
    }
}

 

日历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
  
public class DateDemo {
    public static void main(String[] args) {
        Date now = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        String dataStr = simpleDateFormat.format(now);
  
        System.out.println("今天的日期是"+dataStr);
        System.out.println("今天的日期是"+now);
  
  
        Calendar calendar=Calendar.getInstance();
        System.out.println(calendar);
        System.out.println(calendar.getTime());
        System.out.println(calendar.get(Calendar.YEAR));
        System.out.println(calendar.get(Calendar.MONTH));//0是一月,少一个月
        System.out.println(calendar.get(Calendar.DAY_OF_WEEK));//星期天是第一天
        calendar.add(Calendar.MONTH,1);
        System.out.println("一个月后:"+calendar.getTime());
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
import java.text.SimpleDateFormat;
import java.util.Calendar;
  
public class TestCalendar {
    public static void main(String[] args) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
        Calendar calendar=Calendar.getInstance();
        calendar.set(2012,4,6);
        System.out.println(simpleDateFormat.format(calendar.getTime())+"是一年中的第"+calendar.get(Calendar.WEEK_OF_YEAR)+"星期");
    }
}

 

字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
public class item02 {
    public static void main(String[] args) {
        String str="hello";
        String num="12345";
        String str1= new String("good");
        System.out.println(str.length());//长度public enum Season {
    Spring("春天","春意盎然"),
    Summer("夏天","夏日炎炎"),
    ;
    private String seasonName;
    private String seasonDesc;
  
    Season(String seasonName, String seasonDesc) {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }
  
    public String getSeasonName() {
        return seasonName;
    }
  
    public void setSeasonName(String seasonName) {
        this.seasonName = seasonName;
    }
  
    public String getSeasonDesc() {
        return seasonDesc;
    }
  
    public void setSeasonDesc(String seasonDesc) {
        this.seasonDesc = seasonDesc;
    }
}
public class TestSeason {
    public static void main(String[] args) {
        Season spring = Season.Spring;
        System.out.println(spring.getSeasonName()+"---"+spring.getSeasonDesc());
    }
}
public class MyException extends Exception{//自定义异常
    private int errorCode;//异常编码
  
    public int getErrorCode() {
        return errorCode;
    }
  
    public void setErrorCode(int errorCode) {
        this.errorCode = errorCode;
    }
  
    public MyException() {
    }
  
    public MyException(int errorCode,String msg) {
        super(msg);
        this.errorCode = errorCode;
    }
}
public static void main(String[] args) {
        System.out.println("请输入1~3之间的任何一个数:");
        Scanner input = new Scanner(System.in);
        try{
            int num=input.nextInt();
            if (num==1){
                System.out.println("课程1");
            }else if (num==2){
                System.out.println("课程2");
            }else if(num==3){
                System.out.println("课程3");
            }else {
                System.out.println("输入错误,输入的数不在1~3之间");
            }
        }catch (Exception e){
            System.out.println("输出错误,发生异常");
        }finally {
            System.out.println("欢迎提出建议");
        }
    }
public class Item07 {
    private int age;
    public void setAge(int age) throws MyException{
        if (age<=100&&0<=age){
            this.age=age;
        }else {
            throw new MyException(1001,"年龄必须在1到100岁之间");
        }
    }
    public static void main(String[] args) {
        Item07 item07 = new Item07();
        try {
            item07.setAge(101);
        } catch (MyException e) {
            System.out.println("异常编码:"+e.getErrorCode()+"异常信息:"+e.getMessage());
        }
    }
}
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
  
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
  
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    int age() default 20;
}
import java.lang.annotation.Annotation;
  
public class Person {
    @Deprecated
    private String name;
    @MyAnnotation(age = 16)
    private int age;
  
    public void sayHi(){
  
    }
  
    @MyAnnotation(age = 16)
    public void setAge(){
  
    }
  
    public void checkAge() throws NoSuchFieldException, NoSuchMethodException {
        //通过反射加载Person类,并获取名为"age"的属性下的所有注解
//        Annotation[] annotations = Person.class.getDeclaredField("age").getAnnotations();//getField("age").getAnnotations();
        Annotation[] annotations = Person.class.getMethod("setAge").getAnnotations();
        //遍历输出
        for (Annotation a : annotations) {
            if (a instanceof MyAnnotation){//找到自定义注解
                if (((MyAnnotation)a).age()<18){//读取注解中的年龄信息,并进行判断
                    System.out.println("未成年");
                }else {
                    System.out.println("具备选举权");
                }
            }
        }
    }
  
    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
        Person person = new Person();
        person.checkAge();
    }
}
//第一种:对象名.getClass();
Student student = new Student("jack", 10);
Class aClass=student.getClass();
//第二种:类名.class;
Class aClass = Student.class;
//第三种:Class.forName("加载类的所在路径")
Class aClass = Class.forName("com.cx.demo.Student");
Class aClass = Class.forName("com.cx.demo.Student");
//1.调用无参数的构造方法
Student student =(Student) aClass.newInstance();//创建一个实例
//2.调用指定构造方法getDeclaredFields(指定构造方法对应参数的数据类型)
Constructor con = aClass.getDeclaredConstructor(String.class,int.class);
Student ton = (Student)con.newInstance("ton", 23);//创建一个实例
Class clazz = Class.forName("com.cx.demo.Student");
Student stu = (Student) clazz.newInstance();//属性是对象的一部分
//getDeclaredFields():所有属性,包括私有的
Field[] declaredFields = clazz.getDeclaredFields();
//getDeclaredField("属性名"):指定属性
Field name = clazz.getDeclaredField("name");
//stu.setName设置属性值
name.setAccessible(true);//使得可以获取私有属性 如果是private属性,必须设置为true
name.set(stu,"张三");
Class clazz = Class.forName("com.cx.demo.Student");
Student stu = (Student) clazz.newInstance();
//1.得到方法getDeclaredMethod("方法名",方法所带参数的数据类型)
Method show = clazz.getDeclaredMethod("show", String.class);
//2.动态调用方法invoke(所属对象,传入的参数)
show.invoke(stu,"反射太麻烦了");
//所有的方法,不包括过构造方法
Method[] declaredMethods = aClass.getDeclaredMethods();
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
  
public class TestDate {
    //"2022-10-18"-->Date
    public static void main(String[] args) {
        String str = "2022-10-18";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = sdf.parse(str);//String--->Date
            System.out.println(date);
            String format = sdf.format(date);//Date---->String
            System.out.println(format);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}
import java.text.SimpleDateFormat;
import java.util.Date;
  
public class DateUtil {
    //日期格式
    private static final String pattern="yyyy-MM-dd";
    private static final SimpleDateFormat sdf=new SimpleDateFormat(pattern);
    //将字符串转换成日期
    public static Date convertToDate(String str) throws Exception{
        Date date=null;
        date=sdf.parse(str);
        return date;
    }
    //将日期转换字符串
    public static String convertToString(Date date){
        String str=null;
        str=sdf.format(date);
        return str;
    }
}
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
  
public class DateDemo {
    public static void main(String[] args) {
        Date now = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        String dataStr = simpleDateFormat.format(now);
  
        System.out.println("今天的日期是"+dataStr);
        System.out.println("今天的日期是"+now);
  
  
        Calendar calendar=Calendar.getInstance();
        System.out.println(calendar);
        System.out.println(calendar.getTime());
        System.out.println(calendar.get(Calendar.YEAR));
        System.out.println(calendar.get(Calendar.MONTH));//0是一月,少一个月
        System.out.println(calendar.get(Calendar.DAY_OF_WEEK));//星期天是第一天
        calendar.add(Calendar.MONTH,1);
        System.out.println("一个月后:"+calendar.getTime());
    }
}
import java.text.SimpleDateFormat;
import java.util.Calendar;
  
public class TestCalendar {
    public static void main(String[] args) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
        Calendar calendar=Calendar.getInstance();
        calendar.set(2012,4,6);
        System.out.println(simpleDateFormat.format(calendar.getTime())+"是一年中的第"+calendar.get(Calendar.WEEK_OF_YEAR)+"星期");
    }
}
public class item02 {
    public static void main(String[] args) {
        String str="hello";
        String num="12345";
        String str1= new String("good");
        System.out.println(str.length());//长度
        System.out.println(str.charAt(2));//取字符
        System.out.println(str.indexOf("l"));//取字符下标
        System.out.println(str.concat(str1));//拼接
        System.out.println(str.substring(3, 5));//(]
    }
}
import java.util.Scanner;
  
public class Item05 {
    public static void main(String[] args) {
        char c;
        String str;
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个字符串");
        str=scanner.next();
        System.out.println("请输入要查找的字符");
        c=scanner.next().charAt(0);
        if (str.indexOf(c)>-1){
            int count=0;
            for (int i = 0; i < str.length(); i++) {
                if (c==(str.charAt(i))){
                    count++;
                }
            }
            System.out.println(str+"中包含"+count+"个"+c);
        }else {
            System.out.println(str+"中不存在"+c);
        }
    }
}
public class Item06 {
    public static void main(String[] args) {
        String s = new String();
        StringBuffer stringBuffer = new StringBuffer("1234556");
        //千位分隔符
        for (int i = stringBuffer.length() - 3; i > 0; i -= 3) {
            stringBuffer.insert(i, ",");
        }
        System.out.println(stringBuffer);
    }
}
import java.io.File;
import java.io.IOException;
  
public class TestFile {
    public static void main(String[] args) {
        File dir=new File("/tmp/Temp/temp");
        File file = new File(dir,"text.txt");
  
        if (!dir.exists()){
            dir.mkdir();//创建目录
        }
        if (!file.exists()){//判断文件是否存在
            try {
                file.createNewFile();//创建文件
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else {
            System.out.println(file.getPath());
            System.out.println(file.getName());
            file.delete();//删除文件
            dir.delete();//删除目录
        }
        System.out.println(file.exists());
    }
}
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
  
public class Main {
    public static void main(String[] args) {
        File dir = new File("/tmp/Temp/temp");
        File file = new File("/tmp/Temp/temp/test.txt");
        if (!dir.exists()) {
            dir.mkdir();//新建目录
        }
        if (!file.exists()) {
            try {
                file.createNewFile();//新建文件
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //读取文件
        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            int num = fileInputStream.read();//一次读取一个字节
            System.out.println(num);
            int contentLength;
            byte[] bytes= new byte[1024];
            String content=null;
            //超过1kb
            while ((contentLength = fileInputStream.read(bytes))!=-1){
                content=new String(bytes,0,contentLength);//转化成字符串
            }
            System.out.println(content);
            fileInputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
  
public class FileWriteDemo {
    public static void main(String[] args) {
        try {
            FileOutputStream fileOutputStream = new FileOutputStream("/tmp/Temp/temp/good.txt");
            String msg="weekend";
            byte[] bytes=msg.getBytes(StandardCharsets.UTF_8);
            fileOutputStream.write(bytes,0,bytes.length);//写文件
            fileOutputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
  
public class BufferReaderDemo {
    public static void main(String[] args) {
        try {
            BufferedReader bufferedReader = new BufferedReader(new FileReader("/tmp/Temp/temp/test.txt"));
//            int read = bufferedReader.read();//再次读取有可能丢失首字母
//            System.out.println(read);
            //按行读取
//            String readLine = null;
//            while ((readLine = bufferedReader.readLine()) != null) {
//                System.out.println(readLine);
//            }
            //读取十个字符
//            char[] chars = new char[10];
//            int length = bufferedReader.read(chars, 0, chars.length);
//            System.out.println(length);
//            System.out.println(new String(chars,0,length));
            //超过十个字符
//            char[] chars = new char[10];
//            int length=0;
//            while ((length=bufferedReader.read(chars,0,chars.length))!=-1){
//                System.out.println(new String(chars,0,length));
//            }
  
            bufferedReader.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
  
public class BufferWriterDemo {
    public static void main(String[] args) {
        try {
            BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("/tmp/Temp/temp/new.txt"));
            bufferedWriter.write("first line");
            bufferedWriter.newLine();//换行
            bufferedWriter.write("second line");
            bufferedWriter.newLine();
            bufferedWriter.flush();//清楚空余
            bufferedWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
import java.io.*;
  
public class ObjectDemo {
    public static void main(String[] args) {
//        Student student = new Student("jack",20);
        try {
            //对象的序列化
//            FileOutputStream fileOutputStream = new FileOutputStream("/tmp/Temp/temp/student.bin");
//            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
//
//            objectOutputStream.writeObject(student);
//            objectOutputStream.close();
//            fileOutputStream.close();
  
            //反序列化
  
            FileInputStream fileInputStream = new FileInputStream("/tmp/Temp/temp/student.bin");
            ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
            Student student = (Student) objectInputStream.readObject();
            System.out.println(student);
            fileInputStream.close();
  
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
public interface Person<T> {
    T getName();
    void setName(T t);
}
public class Student<T> implements Person{
    private T t;
  
    public Student() {
    }
  
    public Student(T t) {
        this.setName(t);
    }
  
    public void show(T t){
        System.out.println(t.getClass().getName());
        System.out.println(t);
    }
  
    public T getT() {
        return t;
    }
  
    public void setT(T t) {
        this.t = t;
    }
  
    @Override
    public T getName() {
        return this.t;
    }
  
    @Override
    public void setName(Object o) {
        this.t= (T) o;
    }
    public static void main(String[] args) {
//        Student<String> student=new Student<>();
//        student.show("jack");
        Student<String> student = new Student<>("张三");
        System.out.println(student.getName());
        System.out.println(student.getT().getClass().getName());
    }
  
}
//1.定义线程:通过继承的方式
public class MyThread extends Thread{
    //重写run
  
  
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            //当前运行的是哪个线程
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
  
    public static void main(String[] args) {
  
        //cpu会随机执行里面的线程:主线程,自定义线程
  
        //2.创建线程对象
        MyThread myThread = new MyThread();
        //3.启动线程
        myThread.setName("我的线程");//定义线程名
        myThread.start();
  
        //主线程
        for (int i = 0; i < 5; i++) {
            //当前运行的是哪个线程
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}
public class MyRun implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            //当前运行的是哪个线程
            System.out.println(Thread.currentThread().getName()+":"+i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
  
    public static void main(String[] args) throws InterruptedException {
//        MyRun myRun = new MyRun();
//        new Thread(myRun,"自定义线程名").start();//Thread才是真正的线程
//
//        //主线程
//        for (int i = 0; i < 5; i++) {
//            //当前运行的是哪个线程
//            System.out.println(Thread.currentThread().getName()+":"+i);
//        }
        //优先级只是cpu执行该线程的一个重要参考要素之一
  
  
        MyRun myRun = new MyRun();
  
        Thread t1 = new Thread(myRun, "线程1");
        Thread t2 = new Thread(myRun, "线程2");
        t1.setPriority(4);
        t2.setPriority(6);
        t1.start();
//        t2.start();
        for (int i = 0; i < 5; i++) {
            //当前运行的是哪个线程
            System.out.println(Thread.currentThread().getName()+":"+i);
            Thread.sleep(500);
        }
    }
}
public class ShareApple implements Runnable {
    private int count = 5;//苹果的总数
    private boolean flag = true;//标记位,是否可以拿苹果
  
    //拿苹果的方法
    //同步方法
    public synchronized boolean getApple() {
//        synchronized (this) {//同步代码块
        if (count == 0)//是否有苹果
            return false;
            count--;
            try {
                Thread.sleep(800);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (count >= 0) {
                System.out.println(Thread.currentThread().getName() + "成功拿到了一个苹果,还剩" + count + "个苹果");
            } else {
                System.out.println(Thread.currentThread().getName() + "没有拿到苹果");
            }
            return true;
//        }
    }
  
    @Override
    public void run() {
        while (flag)
            flag = getApple();
        if (count == 0) {
            System.out.println(Thread.currentThread().getName() + "线程结束");
        }
    }
  
  
}
public class TestApple {
    public static void main(String[] args) {
        ShareApple shareApple = new ShareApple();
  
        new Thread(shareApple,"小明").start();
        new Thread(shareApple,"小黑").start();
    }
}
public class Account {
    private int balance = 500;
  
    public int getBalance() {
        return balance;
    }
  
    public void qu(int atm) {
        balance -= atm;
    }
}
public class TestAccount implements Runnable {
    private Account account = new Account();
  
    @Override
    public void run() {
        for (int i = 0; i < 4; i++) {
            makeWithDraw(100);
            if (account.getBalance() < 0)
                System.out.println("账户透支");
        }
    }
  
    private void makeWithDraw(int atm) {
        synchronized (account) {
            if (account.getBalance() >= atm) {
                System.out.println(Thread.currentThread().getName() + "\t准备取款!");
                account.qu(atm);
  
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"\t完成取款");
  
            }else {
                System.out.println("余额不足以支付\t"+Thread.currentThread().getName()+"\t取款的余额为"+account.getBalance());
            }
        }
    }
  
    public static void main(String[] args) {
        TestAccount testAccount = new TestAccount();
        Thread p1 = new Thread(testAccount, "张三");
        Thread p2 = new Thread(testAccount, "张三的妻子");
  
        p1.start();
        p2.start();
    }
}
public class Consumer extends Thread {//消费者
    private ShareData data;
  
    Consumer(ShareData data) {
        this.data = data;
    }
  
    @Override
    public void run() {
        char s;
        do {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            s = data.getChar();
        } while (s != 'D');
    }
}
public class Producer extends Thread {
    private ShareData data;
  
    Producer(ShareData data) {
        this.data = data;
    }
  
    @Override
    public void run() {
        //专门生产
        for (char i = 'A'; i <= 'D'; i++) {
            data.produce(i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class ShareData {
    private char c;
    private boolean flag = false;//信号量
  
    //生产资源
    public synchronized void produce(char c) {
        while (flag) {
            try {
                System.out.println("生产资源:消费者还没有消费,需要等待消费者进行消费");
                wait();//线程立即挂起,释放锁和cpu资源
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        flag = true;
        notify();
        this.c = c;
        System.out.println("生产资源:生产者已经生产了产品" + c + ",等待消费者消费");
    }
  
    //消费资源
    public synchronized char getChar() {
        while (!flag) {
            try {
                System.out.println("消费资源:生产者还没有生产,无法消费消费。。。");
                wait();//线程立即挂起,释放锁和cpu资源
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        flag = false;
        notify();
        System.out.println("消费资源:消费者消费了产品" + c + "通知生产者生产");
        return c;
    }
}
public class TestConsumer {
    public static void main(String[] args) {
        ShareData data = new ShareData();
        new Producer(data).start();
        new Consumer(data).start();
        //定义了两个线程:每一次 都来争夺cpu资源
    }
}
public class DeadLockRunnable implements Runnable {
    //编号
    public int num;
    //资源
    private static Object chopsticks1 = new Object();
    private static Object chopsticks2 = new Object();
  
    private boolean flag =false;//信号量
  
    /**
     * num = 1 拿到chopsticks1 等待chopsticks2
     * num = 2 拿到chopsticks2 等待chopsticks1
     */
  
    @Override
    public void run() {
        if (num==1){
            System.out.println(Thread.currentThread().getName()+"拿到了chopsticks1,等待chopsticks2");
            synchronized (chopsticks1){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (chopsticks2){
                    System.out.println(Thread.currentThread().getName()+"用餐完毕");
                }
            }
        }
        else if (num==2){
            System.out.println(Thread.currentThread().getName()+"拿到了chopsticks2,等待chopsticks1");
            synchronized (chopsticks2){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (chopsticks1){
                    System.out.println(Thread.currentThread().getName()+"用餐完毕");
                }
            }
        }
    }
}
public class DeadLockTest {
    public static void main(String[] args) {
        DeadLockRunnable deadLockRunnable1 = new DeadLockRunnable();
        deadLockRunnable1.num=1;
        DeadLockRunnable deadLockRunnable2 = new DeadLockRunnable();
        deadLockRunnable2.num=2;
        new Thread(deadLockRunnable1,"张三").start();
        new Thread(deadLockRunnable2,"李四").start();
    }
}
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
  
public class Client {
    public static void main(String[] args) throws IOException {//客户端
        //创建Socket
        Socket socket = new Socket(InetAddress.getLocalHost(),9000);
        //得到输出流
        OutputStream os = socket.getOutputStream();
  
        //写入字符串
//        String msg="你好,服务器端,这是用户登录信息";
//        os.write(msg.getBytes(StandardCharsets.UTF_8));
  
        //写入对象
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(os);
        User user = new User("Jack","123");
        objectOutputStream.writeObject(user);
  
        //告诉服务器,消息发完了
        socket.shutdownOutput();
  
  
        //得到输入流
        InputStream is = socket.getInputStream();
        //读取信息
        byte[] by = new byte[1024];
        int len ;//= is.read(by);
        String content=null;
        //超过1kb
        while ((len=is.read(by))!=-1){
            content=new String(by,0,len);
        }
        System.out.println("客户端发送的信息是:"+content);
  
  
  
        //告诉服务器,消息发完了
//        socket.shutdownOutput();
  
        //关闭
        is.close();
        os.close();
        socket.close();
    }
}
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
  
public class MyServer {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //1.创建的是ServerSocket,指定对应的端口号
        System.out.println("服务器请求链接");
        ServerSocket serverSocket = new ServerSocket(9000);
        //2.等待链接
        Socket socket = serverSocket.accept();
        System.out.println("服务器等待链接");
        //3.得到输入流,其实就是客户端的输出流
        InputStream is = socket.getInputStream();
        //4.1读取字符串信息
//        byte[] by = new byte[1024];
//        int len;//= is.read(by);
//        String content = null;
//        //超过1kb
//        while ((len = is.read(by)) != -1) {
//            content = new String(by, 0, len);
//        }
//        System.out.println("客户端发送的信息是:" + content);
  
        //4.2读取对象
        ObjectInputStream ois = new ObjectInputStream(is);
        User user = (User) ois.readObject();
        String msg2=null;
        if ("123".equals(user.getPassword())){
            msg2="欢迎你"+user.getUsername();
        }else {
            msg2="用户名或密码错误";
        }
        System.out.println(msg2);
  
  
        //得到输出流,对客户端进行响应
        OutputStream os = socket.getOutputStream();
        String msg = "你好,客户端,信息已经收到";
        //writer
        os.write(msg.getBytes(StandardCharsets.UTF_8));
  
  
  
        //5.关闭资源
        is.close();
        os.close();
        socket.close();
        serverSocket.close();
    }
}
import java.io.Serializable;
  
public class User implements Serializable {
    private String username;
    private String password;
  
    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
  
    public String getUsername() {
        return username;
    }
  
    public void setUsername(String username) {
        this.username = username;
    }
  
    public String getPassword() {
        return password;
    }
  
    public void setPassword(String password) {
        this.password = password;
    }
}
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
  
public class LoginServer {//多线程处理客户端
  
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(9000);
        Socket socket;
  
        System.out.println("服务器等待请求。。。。");
        while (true) {//实现一直监听
            socket = serverSocket.accept();
            System.out.println("服务器接收到请求");
            //多线程
            LoginThread thread = new LoginThread(socket);
            thread.start();
        }
    }
}
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
  
public class LoginClient1 {
    public static void main(String[] args) throws IOException {
        User user = new User("张三", "123");
  
        Socket socket = new Socket(InetAddress.getLocalHost(), 9000);
  
        OutputStream os = socket.getOutputStream();
        InputStream is = socket.getInputStream();
  
        ObjectOutputStream oos = new ObjectOutputStream(os);
        ObjectInputStream ois = new ObjectInputStream(is);
  
        System.out.println("我是客户端1,给服务器发送登录信息。。。");
        oos.writeObject(user);
        //告诉服务已经发送完了消息
        socket.shutdownOutput();
        //接收服务器的信息
        byte[] temp = new byte[1024];
        int len = is.read(temp);
        System.out.println("服务器的响应"+new String(temp,0,len));
        socket.close();
    }
}
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
  
public class LoginClient2 {
    public static void main(String[] args) throws IOException {
        User user = new User("李四", "123");
        Socket socket = new Socket(InetAddress.getLocalHost(), 9000);
        OutputStream os = socket.getOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(os);
        InputStream is = socket.getInputStream();
        ObjectInputStream ois = new ObjectInputStream(is);
  
        System.out.println("我是客户端2,给服务器发送信息");
        oos.writeObject(user);
        //告诉服务已经发送完了消息
        socket.shutdownOutput();
        //接收服务器的信息
        byte[] temp = new byte[1024];
        int len = is.read(temp);
        System.out.println("服务器的响应"+new String(temp,0,len));
        socket.close();
    }
}
import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
  
public class LoginThread extends Thread {
  
    private Socket socket;
  
    public LoginThread(Socket socket) {
        this.socket = socket;
    }
  
  
    @Override
    public void run() {
        //处理客户端请求
        try (//写在小括号里会自动关闭资源close
                InputStream is = socket.getInputStream();
                OutputStream os = socket.getOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(os);
                ObjectInputStream ois = new ObjectInputStream(is);
        ) {
  
            //得到客户端的信息
            User user = (User) ois.readObject();
            //给客户端回信息
            String msg = null;
            if (user == null) {
                msg = "没有发送登录信息,登录失败";
            } else {
                msg = "欢迎你" + user.getUsername();
            }
            System.out.println(msg);
  
            os.write(msg.getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
import java.net.InetAddress;
import java.net.UnknownHostException;
  
public class TestAddress {
    public static void main(String[] args) throws UnknownHostException {
        //InetAddress:IP地址包装类
        InetAddress localHost = InetAddress.getLocalHost();
        System.out.println(localHost.getHostAddress());//ip地址
        System.out.println(localHost.getHostName());//主机名
        //得到网络主机名
        InetAddress address = InetAddress.getByName("www.baidu.com");
        System.out.println(address.getHostAddress());
        System.out.println(address.getHostName());
    }
}  
import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;
  
public class UDPSend {//发送端
  
    public static void main(String[] args) throws IOException {
        DatagramSocket ds = new DatagramSocket();
        byte[] msg = "最新的邮件来了。。。。".getBytes(StandardCharsets.UTF_8);
        //创建数据包,即将发送出去的数据包,发送的内容,收获的ip,端口号,
        DatagramPacket dp = new DatagramPacket(msg, 0, msg.length, InetAddress.getByName("localhost"), 9000);
        //发送数据
        ds.send(dp);
        //关闭资源:socket
        ds.close();
    }
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
  
public class UDPReceive {
    public static void main(String[] args) throws IOException {//接收端
        //1.创建DatagramSocket
        DatagramSocket ds = new DatagramSocket(9000);
        //2.创建Packet
        byte[] temp = new byte[1024];
        DatagramPacket dp = new DatagramPacket(temp, temp.length);
        //3.接收数据
        ds.receive(dp);
        //发送方的主机名
        String hostName = dp.getAddress().getHostName();
        //发送方的端口号
        int port = dp.getPort();
        System.out.println("发送方的主机名是"+hostName+"发送方的端口号是"+port);
        byte[] bytes = dp.getData();//获取接收到的内容
        String msg=new String(bytes,0, dp.getLength());
        System.out.println("发送过来的信息是:"+msg);
        //4.关闭资源
        ds.close();
    }
}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE students SYSTEM "student.dtd">
<students>
    <student id="1">
        <name>王同</name>
        <class>java</class>
        <score>89</score>
    </student>
    <student id="2">
        <name>李佳</name>
        <class>sql</class>
        <score>58</score>
    </student>
    <student id="3">
        <name>李白</name>
        <class>python</class>
        <score>90</score>
    </student>
</students>
<!ELEMENT students (student+)>
<!ELEMENT student (name,class,score)>
<!ATTLIST student id CDATA #IMPLIED>
<!ELEMENT name (#PCDATA)>
<!ELEMENT class (#PCDATA)>
<!ELEMENT score (#PCDATA)>
public class TestXML {
    public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException {
        //1.得到document
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
        //2.解析和加载xml文件到内存中去
        Document document = documentBuilder.parse("student.xml");
        //3.返回文档中的所有子节点
        NodeList nodeList = document.getChildNodes();
        Node root = nodeList.item(nodeList.getLength() - 1);
        System.out.println("root:" + root.getNodeName());//students
        //4.再查找他的子节点
        NodeList childNodes = root.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node item = childNodes.item(i);
            if ("student".equals(item.getNodeName())) {
                NodeList nodes = item.getChildNodes();
                for (int j = 0; j < nodes.getLength(); j++) {
                    Node node = nodes.item(j);
                    if ("name".equals(node.getNodeName())) {
                        System.out.println("name:" + node.getTextContent());
                    } else if ("class".equals(node.getNodeName())) {
                        System.out.println("class:" + node.getTextContent());
                    } else if ("score".equals(node.getNodeName())) {
                        System.out.println("score:" + node.getTextContent());
                    }
                }
            }
        }
    }
}
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
  
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.FileOutputStream;
import java.io.IOException;
  
public class UpdateXML {
    public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException, TransformerException {
        //使用DOM对XML文件进行数据修改
        //1.得到document
        DocumentBuilderFactory dbf;
        dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
        //解析和加载xml文件到内存中去
        Document document = documentBuilder.parse("student.xml");
        //1.删除某个节点
//        NodeList list = document.getElementsByTagName("student");
//        for (int i = 0; i < list.getLength(); i++) {
//            Element item = (Element)list.item(i);
//            //node:节点(文本节点),element:元素
//            //凡是元素都是节点,但是节点不一定都是元素,例如:一个单纯的回车也是节点
////            System.out.println(item.getAttribute("id"));
//            if ("2".equals(item.getAttribute("id"))){
//                item.getParentNode().removeChild(item);
//            }
//        }
  
  
        //2.添加节点
//        //student(name class score)
//        Element student = document.createElement("student");
//        student.setAttribute("id", "3");//设置属性值
//        //name
//        Element stuName = document.createElement("name");//创建节点
//        stuName.setTextContent("李白");//设置节点内容
//        student.appendChild(stuName);//添加节点
//        //class
//        Element stuClass = document.createElement("class");
//        stuClass.setTextContent("python");
//        student.appendChild(stuClass);
//        //score
//        Element stuScore = document.createElement("score");
//        stuScore.setTextContent("90");
//        student.appendChild(stuScore);
//        //找到根节点students
//        NodeList nodeList = document.getElementsByTagName("students");
//        Node students = nodeList.item(nodeList.getLength() - 1);
//        students.appendChild(student);
  
        //修改:李白-》李清照
        //1.查找节点
        NodeList student3 = document.getElementsByTagName("student");
        for (int i = 0; i < student3.getLength(); i++) {
            Element item = (Element)student3.item(i);
            if ("3".equals(item.getAttribute("id"))){
                Node name = item.getElementsByTagName("name").item(0);
                //2.修改节点内容
                name.setTextContent("李清照");
                break;
            }
        }
  
  
        //保存成XML文件
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        DOMSource domSource = new DOMSource(document);
        // 设置编码类型
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        StreamResult result = new StreamResult(new FileOutputStream("student.xml"));
        // 把DOM树转换为XML文件
        transformer.transform(domSource, result);
  
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<books>
    <book id="book1">
        <name>三国演义</name>
        <price>99.88</price>
    </book>
    <book id="book2">
        <name>西游记</name>
        <price>77.88</price>
    </book>
    <book id="book3">
        <name>李白的诗</name>
        <price>88.88</price>
    </book>
</books>
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
  
import java.util.Iterator;
import java.util.List;
  
public class TestDom01 {
    public static void main(String[] args) throws DocumentException {
        SAXReader saxReader = new SAXReader();
        Document doc = saxReader.read("books.xml");
        //得到根节点
        Element root = doc.getRootElement();
        System.out.println(root.getName());//root
        //遍历显示所有的数据
        List<Element> list = root.elements("book");
        for (Element book:list){
            Attribute id = book.attribute("id");
            System.out.println("id:"+id.getValue());
            //迭代器
            Iterator<Element> it = book.elementIterator();
            while (it.hasNext()){
                Element element = it.next();
                System.out.println(element.getName()+":"+element.getText());
            }
            System.out.println("----------------");
        }
    }
}
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
  
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
  
public class TestDom02 {
    public static void main(String[] args) throws DocumentException, IOException {
        //需求:实现 删除 id="book3"这样的一个节点
        /*
        <book id="book">
        <name>李白的诗</name>
        <price>88.88</price>
        </book>
         */
        //解析xml文件
        SAXReader saxReader = new SAXReader();
        Document doc = saxReader.read("books.xml");
        //得到根节点
        Element root = doc.getRootElement();
        //找到相应的节点
        List<Element> bookList = root.elements("book");
        for (Element book:bookList){
            Attribute id = book.attribute("id");
            if ("book3".equals(id.getValue())){
                book.getParent().remove(book);//删除
            }
        }
        //保存到xml文件
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        XMLWriter writer = new XMLWriter(new FileWriter("books.xml"));
        writer.write(doc);
        writer.close();
        System.out.println("删除成功");
    }
}
import org.dom4j.*;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
  
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
  
public class TestDom03 {
    public static void main(String[] args) throws DocumentException, IOException {
        //需求:实现 新增节点
        /*
        <book id="book">
        <name>李白的诗</name>
        <price>88.88</price>
        </book>
         */
        //解析xml文件
        SAXReader saxReader = new SAXReader();
        Document doc = saxReader.read("books.xml");
        //得到根节点
        Element root = doc.getRootElement();
        //新增节点
        Element book = DocumentHelper.createElement("book");
        book.addAttribute("id", "book3");
  
        Element name = DocumentHelper.createElement("name");//创建节点
        name.setText("李白的诗");//设置属性
        book.add(name);//添加节点
  
        Element price = DocumentHelper.createElement("price");
        price.setText("88.88");
        book.add(price);
        root.add(book);
        //保存到xml文件
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        XMLWriter writer = new XMLWriter(new FileWriter("books.xml"));
        writer.write(doc);
        writer.close();
        System.out.println("新增成功");
    }
}
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
  
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
  
public class TestDom04 {
    public static void main(String[] args) throws DocumentException, IOException {
        //需求 实现 修改 id="book3"这样的一个节点 李白的诗-》李清照的诗句2.外部类外部:StaticInnerClass.Inner inne
        SAXReader saxReader = new SAXReader();
        Document doc = saxReader.read("books.xml");
        //得到根节点
        Element root = doc.getRootElement();
        System.out.println(root.getName());//root
        //遍历所有的数据
        List<Element> list = root.elements("book");
        for (Element book : list) {
            //找到对应的节点
            if ("book3".equals(book.attribute("id").getValue())) {
                //迭代器
                Iterator<Element> it = book.elementIterator();
                while (it.hasNext()) {
                    Element element = it.next();
                    //找到要修改的文本
                    if ("李白的诗".equals(element.getText())) {
                        element.setText("李清照的诗");
                        System.out.println(element.getName() + ":" + element.getText());
                        break;
                    }
                }
                break;
            }
        }
        //保存到xml文件
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        XMLWriter writer = new XMLWriter(new FileWriter("books.xml"));
        writer.write(doc);
        writer.close();
        System.out.println("修改成功");
    }
}
import java.util.HashSet;
import java.util.Set;
  
public class Worker {
    private String name;//姓名
    private int age;//年龄
    private int salary;//收入
  
    public Worker(String name, int age, int salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }
  
    @Override
    public String toString() {
        return "Worker{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                '}';
    }
  
    @Override
    public int hashCode() {
        // TODO Auto-generated method stub
        return this.name.hashCode() + age + salary;
    }
  
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (this.getClass() != obj.getClass()) {
            return false;
        }
        Worker obj2 = (Worker) obj;
  
        if (this.name.equals(obj2.name) && this.age == obj2.age && this.salary == obj2.salary) {
            return true;
        }
        return false;
    }
  
    public static void main(String[] args) {
        Set<Worker> hashSet = new HashSet<>();
        //hashcode作为索引或者说是唯一标识
        hashSet.add(new Worker("zhang3", 18, 1500));
        hashSet.add(new Worker("li4", 18, 1500));
        hashSet.add(new Worker("wang5", 18, 1600));
        hashSet.add(new Worker("zhao6", 18, 2000));
        hashSet.add(new Worker("zhao6", 18, 2000));
  
        for (Worker worker : hashSet) {
            System.out.println(worker);
        }
    }
}
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
  
public class Worker implements Comparable {
    private String name;//姓名
    private int age;//年龄
    private int salary;//收入
  
    public Worker(String name, int age, int salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }
  
    public String getName() {
        return name;
    }
  
    public void setName(String name) {
        this.name = name;
    }
  
    public int getAge() {
        return age;
    }
  
    public void setAge(int age) {
        this.age = age;
    }
  
    public int getSalary() {
        return salary;
    }
  
    public void setSalary(int salary) {
        this.salary = salary;
    }
  
    @Override
    public String toString() {
        return "Worker{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                '}';
    }
  
    @Override
    public int compareTo(Object o) {
        if (this == o) {
            return 0;
        } else {
            if (o instanceof Worker) {
                Worker worker = (Worker) o;
                if (this.age != worker.getAge()) {
                    return this.age - worker.getAge();
                } else if (this.salary != worker.getSalary()) {
                    return  this.salary-worker.getSalary();
                } else {
                    return this.name.compareTo(worker.getName());
                }
            } else {
                try {
                    throw new Exception("只能比较Worker对象");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return 0;
    }
  
    public static void main(String[] args) {
        TreeSet<Worker> set = new TreeSet<>();
  
        set.add(new Worker("zhang3", 18, 1500));
        set.add(new Worker("li4", 18, 1500));
        set.add(new Worker("wang5", 18, 1600));
        set.add(new Worker("zhao6", 17, 2000));
  
  
        for (Worker worker : set) {
            System.out.print(worker.getName()+"\t");
        }
    }
}
System.out.println(str.charAt(2));//取字符 System.out.println(str.indexOf("l"));//取字符下标 System.out.println(str.concat(str1));//拼接 System.out.println(str.substring(3, 5));//(] } }

抽象类和抽象方法

1.定义

随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。

类的设计应该保证父类和子类都能够共享特征。

有时候将一个父类设计的非常抽象,以至于他都没有具体的实例,这样的类叫做抽象类。

优势:不能被实例化

2.abstract修饰类:抽象类

抽象类不能实例化

抽象类中一定有构造器,便于子类实例化时调用(涉及:子类实例化的全过程)

开发中,都会提供抽象类的子类,让子类对象使用,完成相关操作。

3.abstract修饰方法:抽象方法

抽象方法只有方法的声明,没有方法体。

包含抽象方法的类,一定是一个抽象方法,然而,抽象类中可以没有抽象方法。

若子类重写类父类中的所有方法后,此子类方可实例化。

若子类没有重写父类中的所有方法抽象方法,

则此子类也是一个抽象类,需要使用abstract修饰该子类。

4.abstract关键字的注意事项

abstract不能用来修饰:属性、构造器等结构。

abstract不能用来修饰私有方法、静态方法、final修饰的方法。

接口

接口的特性:

  属性:需要public static final修饰

  方法:要求public abstract

  没有构造方法,也没有程序块

  接口不能创建对象,子类多实现接口来做事

  接口也是一种引用数据类型

  接口是完全抽象的。(抽象类是半抽象的)或者说,接口是特殊的抽象类。

接口和抽象类的相同点和不同点

可以实现多个接口,不能继承多个类

final关键字

  final可以声明类、属性、方法

  final标记的类不能被继承(final和abstract不能同时存在),没有子类

  final标记的基本数据类型不能被改变//public void func(final int i){i++;}会报错

  final标记的引用数据类型是可以改变其属性的(不改变引用数据类型的地址,不能new)//public void func(final Object o){o.i++;}

  final标记的方法不能被重写,可以重载

  final标记的标量是常量,一般public static final double Pi=3.14,常量可以被私有(goto 和 const在java中是关键字,但不过被使用,这种叫做保留关键字)

枚举

枚举指的是一组固定的常量组成的类型

类型安全:取值只能在涌现的范围内选择

 

 

异常

谁调用,谁处理

异常处理的五个关键字

捕获异常:try/catch/finally

抛出异常:throw  可以手动抛出异常对象;例如throw new Exception("异常信息")

声明异常:throws  声明方法  可能要抛出的各种异常了,向上传递异常,直到Main函数  保证程序可以正常运行

returnType methodName(...) throws Exception{

  throw new Exception("异常信息");

}

运行时异常RuntimeException

Exception---------------------------------------------------------异常层次结构的根类

ArithmeticException--------------------------------------------算术错误情形,如 以零作为除数

ArrayIndexOutOfExceptionBoundsException------------数组下标越界

NullPointerException-------------------------------------------尝试访问null对象成员

NumberFormatException-------------------------------------数字格式转换异常,如 把"abc"转换成数字

检查异常CheckException:检查异常是程序员必须进行处理

何时需要自定义异常

当JDK中的异常不能满足程序需要的时候

自定义异常

 

 

 

注解

内置的注解

Java 定义了一套注解,共有 7 个,3 个在 java.lang 中,剩下 4 个在 java.lang.annotation 中。

作用在代码的注解是

  • @Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。

  • @Deprecated - 标记过时方法。如果使用该方法,会报编译警告。

  • @SuppressWarnings - 指示编译器去忽略注解中声明的警告。

作用在其他注解的注解(或者说 元注解)是:

  • @Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。

  • @Documented - 标记这些注解是否包含在用户文档中。

  • @Target - 标记这个注解应该是哪种 Java 成员。

  • @Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)

从 Java 7 开始,额外添加了 3 个注解:

  • @SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。

  • @FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。

  • @Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。

自定义注解

 

 内部类

内部类与外部类的关系

1.成员内部类的创建需要依赖于外部类对象(成员方法必须用过对象调用),在没有外部类实例之前无法创建成员内部类对象

2.内部类与外部类相对独立,不是is a关系

3.私有属性的相互访问,内部类可以直接访问外部类,而外部类访问内部类需要内部类的对象来访问

4.创建内部类的语法

  在外部类内部创建内部类对象Inner inner = new Inner();

  在外部类外部创建内部类对象,外部类.内部类 inner=new Outer().new Inner();

5.在内部类内部使用隐藏的外部类对象,外部类类名.this

内部类的优势

内部类不受外部类是否继承各类,是多重继承的完美解决方案,是对JAVA单一继承的有益补充

内部类的分类

静态内部类

使用static修饰,类比静态方法,不需要外部类对象产生就内使用

不能访问外部类的成员域,只能访问静态域

创建语法

1.外部类内部:与成员内部类一样

2.外部了外部:Inner inner=new Outer.Inner();

非静态内部类

对外部完全隐藏,因此方法内部类不能用任何的访问修饰符

方法内部类没有访问形参,这个形参是可以在方法中随意修改的,一旦方法内部类中使用了形参,这个形参必须被声明为final

匿名内部类

1.必须继承一个抽象类或者实现一个接口

2.没有构造方法

反射

在编译时不确定哪个类被加载,而在程序运行时才加载、探知、使用

基于Class类

Class类是Java反射机制的起源和入口,每个类都有自己的Class对象,用于获取与类相关的各种信息,提供了获取信息的相关方法,Class类继承自Object类

优点

提高了Java程序的灵活性和扩展性,降低了耦合性

问题

可读性较差,反射会模糊程序内部逻辑

主要使用到的类

Class类---可获取类与类的成员信息

Field类---可访问类的属性

Method类---可调用类的方法

Constructor类---可调用类的构造方法

使用反射机制的一般步骤

1.通过反射加载类(三种方式)

2.通过反射创建对象(两种方式)

3.通过反射操作属性

4.通过反射动态执行方法

 

几个常用的工具类

时间转换类

SimpleDateFormat

使用方法

 工具类案例

 

日历

 

 

字符串

 

 

 

I/O流

 

操作文件

 使用FileInputStream读取文件

 使用FileOutputStream写文件

 使用BufferedReader和FileReader读取文件

 使用BufferedWriter和FileWriter写文件

 

序列化与反序列化

 泛型

 

 

多线程

进程:系统运行的基本单位,有独立的内存空间和系统资源
线程:进程中执行运算的最小单位,处理机分配给线程,即真正在处理机上运行的是线程

线程的创建的两种方式
    继承java.lang.thread类
    实现java.lang.Runnable接口(还是要借助于thread启动)

1.定义线程
2.创建线程对象
3.启动线程
4.终止线程(不推荐手动终止)

cpu会随机执行里面的线程:主线程,自定义线程

线程的声明周期包括四个状态:新生状态,可运行状态,阻塞状态和死亡状态

多个线程处于可运行的状态(线程调度)
    分配优先级 1的优先级最高,默认值是5,Thread.currentThread().getPriority()
    更改优先级 new Thread().setPriority(4)
    
    new Thread().join()添加进阻塞进程
    
    Thread.sleep(500)当前线程停止执行,进入不可运行状态(阻塞),其他等待运行的进程机会是相等的
    
    yield当前线程转入暂停运行的状态(不阻塞),如果没有其他等待执行的线程,当前线程会马上恢复执行,会优先级相同的或更高的执行
    
线程同步
    关键字synchronized
    
    同步方法
    同步代码块
线程通信
    wait()挂起当前线程,并释放共享资源的锁
    notify()在因调用该对象的wait方法二阻塞的线程中随机选择一个解除阻塞,但要等到获得锁后才可以正真执行
    notifyall将因调用该对象的wait方法而阻塞的所有线程一次性全部解除阻塞
    这三个方法只能在同步方法或者同步代码块中使用

线程创建

 

 

分苹果

 

 存取款

 

 生产者消费者模式

 

 

 

 死锁

 

 

线程通信

客户端与服务端

InetAddress类    无构造方法 getLocalHost获取本地ip getByName获取网络主机名

基于tcp:Socket(客户端)和Server Socket(服务器端)
    ServerSocket.accept():获取客户端socket

Socket通信模型
    进行网络通信是,Socket需要借助数据流来完成数据的传递工作
Socket类
    两个Socket类的构造方法及其含义
    Socket socket=new Socker("localhost",8800)
    ServerSocket serverSocket = new ServerSocket(9000);
    
    socket.getOutputStream();
    os.write

    1.建立连接
    2.打开Socket关联的输入输出流
    3.数据流中读写信息
    4.关闭所有的数据流和Socket
ServerSocket类的accept()方法有何用处:获取客户端socket

 

 

 服务器端与多客户端

 

 

 

 网络编程

ip地址与主机名

    C类地址(192.0.0.0-223.255.255.0):192.168.0.0~192.168.255.255
      
InetAddress类    无构造方法 getLocalHost获取本地ip getByName获取网络主机名

基于tcp:Socket(客户端)和Server Socket(服务器端)
    ServerSocket.accept():获取客户端socket

Socket通信模型
    进行网络通信是,Socket需要借助数据流来完成数据的传递工作
Socket类
    两个Socket类的构造方法及其含义
    Socket socket=new Socker("localhost",8800)
    ServerSocket serverSocket = new ServerSocket(9000);
    
    socket.getOutputStream();
    os.write

    1.建立连接
    2.打开Socket关联的输入输出流
    3.数据流中读写信息
    4.关闭所有的数据流和Socket
ServerSocket类的accept()方法有何用处:获取客户端socket

 UDP

基于UDP协议的Socket编程
    1.利用DatagramSocket发送数据包
    2.利用DatagramPacket对象封装数据包
    3.利用DataGramPacket处理数据包
    4.利用DataGramPacket接收数据包
    
    建立发送端,接收端
    创建数据
    建立数据包
    调用Socket的发送接收方法
    关闭SOcket
    发送端与接收端是两个独立运行的程序

 

 DOM文件

 

 

 

 

DOM4j

 

 

 

 

 集合

2.外部类外部:StaticInnerClass.Inner inne

 

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.util.Scanner;
  
public class Item05 {
    public static void main(String[] args) {
        char c;
        String str;
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个字符串");
        str=scanner.next();
        System.out.println("请输入要查找的字符");
        c=scanner.next().charAt(0);
        if (str.indexOf(c)>-1){
            int count=0;
            for (int i = 0; i < str.length(); i++) {
                if (c==(str.charAt(i))){
                    count++;
                }
            }
            System.out.println(str+"中包含"+count+"个"+c);
        }else {
            System.out.println(str+"中不存在"+c);
        }
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
public class Item06 {
    public static void main(String[] args) {
        String s = new String();
        StringBuffer stringBuffer = new StringBuffer("1234556");
        //千位分隔符
        for (int i = stringBuffer.length() - 3; i > 0; i -= 3) {
            stringBuffer.insert(i, ",");
        }
        System.out.println(stringBuffer);
    }
}

 

I/O流

 

操作文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.io.File;
import java.io.IOException;
  
public class TestFile {
    public static void main(String[] args) {
        File dir=new File("/tmp/Temp/temp");
        File file = new File(dir,"text.txt");
  
        if (!dir.exists()){
            dir.mkdir();//创建目录
        }
        if (!file.exists()){//判断文件是否存在
            try {
                file.createNewFile();//创建文件
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else {
            System.out.println(file.getPath());
            System.out.println(file.getName());
            file.delete();//删除文件
            dir.delete();//删除目录
        }
        System.out.println(file.exists());
    }
}

 使用FileInputStream读取文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
  
public class Main {
    public static void main(String[] args) {
        File dir = new File("/tmp/Temp/temp");
        File file = new File("/tmp/Temp/temp/test.txt");
        if (!dir.exists()) {
            dir.mkdir();//新建目录
        }
        if (!file.exists()) {
            try {
                file.createNewFile();//新建文件
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //读取文件
        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            int num = fileInputStream.read();//一次读取一个字节
            System.out.println(num);
            int contentLength;
            byte[] bytes= new byte[1024];
            String content=null;
            //超过1kb
            while ((contentLength = fileInputStream.read(bytes))!=-1){
                content=new String(bytes,0,contentLength);//转化成字符串
            }
            System.out.println(content);
            fileInputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 使用FileOutputStream写文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
  
public class FileWriteDemo {
    public static void main(String[] args) {
        try {
            FileOutputStream fileOutputStream = new FileOutputStream("/tmp/Temp/temp/good.txt");
            String msg="weekend";
            byte[] bytes=msg.getBytes(StandardCharsets.UTF_8);
            fileOutputStream.write(bytes,0,bytes.length);//写文件
            fileOutputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 使用BufferedReader和FileReader读取文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
  
public class BufferReaderDemo {
    public static void main(String[] args) {
        try {
            BufferedReader bufferedReader = new BufferedReader(new FileReader("/tmp/Temp/temp/test.txt"));
//            int read = bufferedReader.read();//再次读取有可能丢失首字母
//            System.out.println(read);
            //按行读取
//            String readLine = null;
//            while ((readLine = bufferedReader.readLine()) != null) {
//                System.out.println(readLine);
//            }
            //读取十个字符
//            char[] chars = new char[10];
//            int length = bufferedReader.read(chars, 0, chars.length);
//            System.out.println(length);
//            System.out.println(new String(chars,0,length));
            //超过十个字符
//            char[] chars = new char[10];
//            int length=0;
//            while ((length=bufferedReader.read(chars,0,chars.length))!=-1){
//                System.out.println(new String(chars,0,length));
//            }
  
            bufferedReader.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 使用BufferedWriter和FileWriter写文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
  
public class BufferWriterDemo {
    public static void main(String[] args) {
        try {
            BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("/tmp/Temp/temp/new.txt"));
            bufferedWriter.write("first line");
            bufferedWriter.newLine();//换行
            bufferedWriter.write("second line");
            bufferedWriter.newLine();
            bufferedWriter.flush();//清楚空余
            bufferedWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

序列化与反序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.io.*;
  
public class ObjectDemo {
    public static void main(String[] args) {
//        Student student = new Student("jack",20);
        try {
            //对象的序列化
//            FileOutputStream fileOutputStream = new FileOutputStream("/tmp/Temp/temp/student.bin");
//            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
//
//            objectOutputStream.writeObject(student);
//            objectOutputStream.close();
//            fileOutputStream.close();
  
            //反序列化
  
            FileInputStream fileInputStream = new FileInputStream("/tmp/Temp/temp/student.bin");
            ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
            Student student = (Student) objectInputStream.readObject();
            System.out.println(student);
            fileInputStream.close();
  
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

 泛型

1
2
3
4
public interface Person<T> {
    T getName();
    void setName(T t);
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class Student<T> implements Person{
    private T t;
  
    public Student() {
    }
  
    public Student(T t) {
        this.setName(t);
    }
  
    public void show(T t){
        System.out.println(t.getClass().getName());
        System.out.println(t);
    }
  
    public T getT() {
        return t;
    }
  
    public void setT(T t) {
        this.t = t;
    }
  
    @Override
    public T getName() {
        return this.t;
    }
  
    @Override
    public void setName(Object o) {
        this.t= (T) o;
    }
    public static void main(String[] args) {
//        Student<String> student=new Student<>();
//        student.show("jack");
        Student<String> student = new Student<>("张三");
        System.out.println(student.getName());
        System.out.println(student.getT().getClass().getName());
    }
  
}

 

多线程

进程:系统运行的基本单位,有独立的内存空间和系统资源
线程:进程中执行运算的最小单位,处理机分配给线程,即真正在处理机上运行的是线程

线程的创建的两种方式
    继承java.lang.thread类
    实现java.lang.Runnable接口(还是要借助于thread启动)

1.定义线程
2.创建线程对象
3.启动线程
4.终止线程(不推荐手动终止)

cpu会随机执行里面的线程:主线程,自定义线程

线程的声明周期包括四个状态:新生状态,可运行状态,阻塞状态和死亡状态

多个线程处于可运行的状态(线程调度)
    分配优先级 1的优先级最高,默认值是5,Thread.currentThread().getPriority()
    更改优先级 new Thread().setPriority(4)
    
    new Thread().join()添加进阻塞进程
    
    Thread.sleep(500)当前线程停止执行,进入不可运行状态(阻塞),其他等待运行的进程机会是相等的
    
    yield当前线程转入暂停运行的状态(不阻塞),如果没有其他等待执行的线程,当前线程会马上恢复执行,会优先级相同的或更高的执行
    
线程同步
    关键字synchronized
    
    同步方法
    同步代码块
线程通信
    wait()挂起当前线程,并释放共享资源的锁
    notify()在因调用该对象的wait方法二阻塞的线程中随机选择一个解除阻塞,但要等到获得锁后才可以正真执行
    notifyall将因调用该对象的wait方法而阻塞的所有线程一次性全部解除阻塞
    这三个方法只能在同步方法或者同步代码块中使用

线程创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//1.定义线程:通过继承的方式
public class MyThread extends Thread{
    //重写run
  
  
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            //当前运行的是哪个线程
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
  
    public static void main(String[] args) {
  
        //cpu会随机执行里面的线程:主线程,自定义线程
  
        //2.创建线程对象
        MyThread myThread = new MyThread();
        //3.启动线程
        myThread.setName("我的线程");//定义线程名
        myThread.start();
  
        //主线程
        for (int i = 0; i < 5; i++) {
            //当前运行的是哪个线程
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class MyRun implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            //当前运行的是哪个线程
            System.out.println(Thread.currentThread().getName()+":"+i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
  
    public static void main(String[] args) throws InterruptedException {
//        MyRun myRun = new MyRun();
//        new Thread(myRun,"自定义线程名").start();//Thread才是真正的线程
//
//        //主线程
//        for (int i = 0; i < 5; i++) {
//            //当前运行的是哪个线程
//            System.out.println(Thread.currentThread().getName()+":"+i);
//        }
        //优先级只是cpu执行该线程的一个重要参考要素之一
  
  
        MyRun myRun = new MyRun();
  
        Thread t1 = new Thread(myRun, "线程1");
        Thread t2 = new Thread(myRun, "线程2");
        t1.setPriority(4);
        t2.setPriority(6);
        t1.start();
//        t2.start();
        for (int i = 0; i < 5; i++) {
            //当前运行的是哪个线程
            System.out.println(Thread.currentThread().getName()+":"+i);
            Thread.sleep(500);
        }
    }
}

 

分苹果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class ShareApple implements Runnable {
    private int count = 5;//苹果的总数
    private boolean flag = true;//标记位,是否可以拿苹果
  
    //拿苹果的方法
    //同步方法
    public synchronized boolean getApple() {
//        synchronized (this) {//同步代码块
        if (count == 0)//是否有苹果
            return false;
            count--;
            try {
                Thread.sleep(800);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (count >= 0) {
                System.out.println(Thread.currentThread().getName() + "成功拿到了一个苹果,还剩" + count + "个苹果");
            } else {
                System.out.println(Thread.currentThread().getName() + "没有拿到苹果");
            }
            return true;
//        }
    }
  
    @Override
    public void run() {
        while (flag)
            flag = getApple();
        if (count == 0) {
            System.out.println(Thread.currentThread().getName() + "线程结束");
        }
    }
  
  
}

 

1
2
3
4
5
6
7
8
public class TestApple {
    public static void main(String[] args) {
        ShareApple shareApple = new ShareApple();
  
        new Thread(shareApple,"小明").start();
        new Thread(shareApple,"小黑").start();
    }
}

 存取款

1
2
3
4
5
6
7
8
9
10
11
public class Account {
    private int balance = 500;
  
    public int getBalance() {
        return balance;
    }
  
    public void qu(int atm) {
        balance -= atm;
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class TestAccount implements Runnable {
    private Account account = new Account();
  
    @Override
    public void run() {
        for (int i = 0; i < 4; i++) {
            makeWithDraw(100);
            if (account.getBalance() < 0)
                System.out.println("账户透支");
        }
    }
  
    private void makeWithDraw(int atm) {
        synchronized (account) {
            if (account.getBalance() >= atm) {
                System.out.println(Thread.currentThread().getName() + "\t准备取款!");
                account.qu(atm);
  
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"\t完成取款");
  
            }else {
                System.out.println("余额不足以支付\t"+Thread.currentThread().getName()+"\t取款的余额为"+account.getBalance());
            }
        }
    }
  
    public static void main(String[] args) {
        TestAccount testAccount = new TestAccount();
        Thread p1 = new Thread(testAccount, "张三");
        Thread p2 = new Thread(testAccount, "张三的妻子");
  
        p1.start();
        p2.start();
    }
}

 生产者消费者模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Consumer extends Thread {//消费者
    private ShareData data;
  
    Consumer(ShareData data) {
        this.data = data;
    }
  
    @Override
    public void run() {
        char s;
        do {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            s = data.getChar();
        } while (s != 'D');
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Producer extends Thread {
    private ShareData data;
  
    Producer(ShareData data) {
        this.data = data;
    }
  
    @Override
    public void run() {
        //专门生产
        for (char i = 'A'; i <= 'D'; i++) {
            data.produce(i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class ShareData {
    private char c;
    private boolean flag = false;//信号量
  
    //生产资源
    public synchronized void produce(char c) {
        while (flag) {
            try {
                System.out.println("生产资源:消费者还没有消费,需要等待消费者进行消费");
                wait();//线程立即挂起,释放锁和cpu资源
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        flag = true;
        notify();
        this.c = c;
        System.out.println("生产资源:生产者已经生产了产品" + c + ",等待消费者消费");
    }
  
    //消费资源
    public synchronized char getChar() {
        while (!flag) {
            try {
                System.out.println("消费资源:生产者还没有生产,无法消费消费。。。");
                wait();//线程立即挂起,释放锁和cpu资源
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        flag = false;
        notify();
        System.out.println("消费资源:消费者消费了产品" + c + "通知生产者生产");
        return c;
    }
}

 

1
2
3
4
5
6
7
8
public class TestConsumer {
    public static void main(String[] args) {
        ShareData data = new ShareData();
        new Producer(data).start();
        new Consumer(data).start();
        //定义了两个线程:每一次 都来争夺cpu资源
    }
}

 死锁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class DeadLockRunnable implements Runnable {
    //编号
    public int num;
    //资源
    private static Object chopsticks1 = new Object();
    private static Object chopsticks2 = new Object();
  
    private boolean flag =false;//信号量
  
    /**
     * num = 1 拿到chopsticks1 等待chopsticks2
     * num = 2 拿到chopsticks2 等待chopsticks1
     */
  
    @Override
    public void run() {
        if (num==1){
            System.out.println(Thread.currentThread().getName()+"拿到了chopsticks1,等待chopsticks2");
            synchronized (chopsticks1){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (chopsticks2){
                    System.out.println(Thread.currentThread().getName()+"用餐完毕");
                }
            }
        }
        else if (num==2){
            System.out.println(Thread.currentThread().getName()+"拿到了chopsticks2,等待chopsticks1");
            synchronized (chopsticks2){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (chopsticks1){
                    System.out.println(Thread.currentThread().getName()+"用餐完毕");
                }
            }
        }
    }
}

 

1
2
3
4
5
6
7
8
9
10
public class DeadLockTest {
    public static void main(String[] args) {
        DeadLockRunnable deadLockRunnable1 = new DeadLockRunnable();
        deadLockRunnable1.num=1;
        DeadLockRunnable deadLockRunnable2 = new DeadLockRunnable();
        deadLockRunnable2.num=2;
        new Thread(deadLockRunnable1,"张三").start();
        new Thread(deadLockRunnable2,"李四").start();
    }
}

 

线程通信

客户端与服务端

InetAddress类    无构造方法 getLocalHost获取本地ip getByName获取网络主机名

基于tcp:Socket(客户端)和Server Socket(服务器端)
    ServerSocket.accept():获取客户端socket

Socket通信模型
    进行网络通信是,Socket需要借助数据流来完成数据的传递工作
Socket类
    两个Socket类的构造方法及其含义
    Socket socket=new Socker("localhost",8800)
    ServerSocket serverSocket = new ServerSocket(9000);
    
    socket.getOutputStream();
    os.write

    1.建立连接
    2.打开Socket关联的输入输出流
    3.数据流中读写信息
    4.关闭所有的数据流和Socket
ServerSocket类的accept()方法有何用处:获取客户端socket

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
  
public class Client {
    public static void main(String[] args) throws IOException {//客户端
        //创建Socket
        Socket socket = new Socket(InetAddress.getLocalHost(),9000);
        //得到输出流
        OutputStream os = socket.getOutputStream();
  
        //写入字符串
//        String msg="你好,服务器端,这是用户登录信息";
//        os.write(msg.getBytes(StandardCharsets.UTF_8));
  
        //写入对象
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(os);
        User user = new User("Jack","123");
        objectOutputStream.writeObject(user);
  
        //告诉服务器,消息发完了
        socket.shutdownOutput();
  
  
        //得到输入流
        InputStream is = socket.getInputStream();
        //读取信息
        byte[] by = new byte[1024];
        int len ;//= is.read(by);
        String content=null;
        //超过1kb
        while ((len=is.read(by))!=-1){
            content=new String(by,0,len);
        }
        System.out.println("客户端发送的信息是:"+content);
  
  
  
        //告诉服务器,消息发完了
//        socket.shutdownOutput();
  
        //关闭
        is.close();
        os.close();
        socket.close();
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
  
public class MyServer {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //1.创建的是ServerSocket,指定对应的端口号
        System.out.println("服务器请求链接");
        ServerSocket serverSocket = new ServerSocket(9000);
        //2.等待链接
        Socket socket = serverSocket.accept();
        System.out.println("服务器等待链接");
        //3.得到输入流,其实就是客户端的输出流
        InputStream is = socket.getInputStream();
        //4.1读取字符串信息
//        byte[] by = new byte[1024];
//        int len;//= is.read(by);
//        String content = null;
//        //超过1kb
//        while ((len = is.read(by)) != -1) {
//            content = new String(by, 0, len);
//        }
//        System.out.println("客户端发送的信息是:" + content);
  
        //4.2读取对象
        ObjectInputStream ois = new ObjectInputStream(is);
        User user = (User) ois.readObject();
        String msg2=null;
        if ("123".equals(user.getPassword())){
            msg2="欢迎你"+user.getUsername();
        }else {
            msg2="用户名或密码错误";
        }
        System.out.println(msg2);
  
  
        //得到输出流,对客户端进行响应
        OutputStream os = socket.getOutputStream();
        String msg = "你好,客户端,信息已经收到";
        //writer
        os.write(msg.getBytes(StandardCharsets.UTF_8));
  
  
  
        //5.关闭资源
        is.close();
        os.close();
        socket.close();
        serverSocket.close();
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.io.Serializable;
  
public class User implements Serializable {
    private String username;
    private String password;
  
    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
  
    public String getUsername() {
        return username;
    }
  
    public void setUsername(String username) {
        this.username = username;
    }
  
    public String getPassword() {
        return password;
    }
  
    public void setPassword(String password) {
        this.password = password;
    }
}

 服务器端与多客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
  
public class LoginServer {//多线程处理客户端
  
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(9000);
        Socket socket;
  
        System.out.println("服务器等待请求。。。。");
        while (true) {//实现一直监听
            socket = serverSocket.accept();
            System.out.println("服务器接收到请求");
            //多线程
            LoginThread thread = new LoginThread(socket);
            thread.start();
        }
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
  
public class LoginClient1 {
    public static void main(String[] args) throws IOException {
        User user = new User("张三", "123");
  
        Socket socket = new Socket(InetAddress.getLocalHost(), 9000);
  
        OutputStream os = socket.getOutputStream();
        InputStream is = socket.getInputStream();
  
        ObjectOutputStream oos = new ObjectOutputStream(os);
        ObjectInputStream ois = new ObjectInputStream(is);
  
        System.out.println("我是客户端1,给服务器发送登录信息。。。");
        oos.writeObject(user);
        //告诉服务已经发送完了消息
        socket.shutdownOutput();
        //接收服务器的信息
        byte[] temp = new byte[1024];
        int len = is.read(temp);
        System.out.println("服务器的响应"+new String(temp,0,len));
        socket.close();
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
  
public class LoginClient2 {
    public static void main(String[] args) throws IOException {
        User user = new User("李四", "123");
        Socket socket = new Socket(InetAddress.getLocalHost(), 9000);
        OutputStream os = socket.getOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(os);
        InputStream is = socket.getInputStream();
        ObjectInputStream ois = new ObjectInputStream(is);
  
        System.out.println("我是客户端2,给服务器发送信息");
        oos.writeObject(user);
        //告诉服务已经发送完了消息
        socket.shutdownOutput();
        //接收服务器的信息
        byte[] temp = new byte[1024];
        int len = is.read(temp);
        System.out.println("服务器的响应"+new String(temp,0,len));
        socket.close();
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
  
public class LoginThread extends Thread {
  
    private Socket socket;
  
    public LoginThread(Socket socket) {
        this.socket = socket;
    }
  
  
    @Override
    public void run() {
        //处理客户端请求
        try (//写在小括号里会自动关闭资源close
                InputStream is = socket.getInputStream();
                OutputStream os = socket.getOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(os);
                ObjectInputStream ois = new ObjectInputStream(is);
        ) {
  
            //得到客户端的信息
            User user = (User) ois.readObject();
            //给客户端回信息
            String msg = null;
            if (user == null) {
                msg = "没有发送登录信息,登录失败";
            } else {
                msg = "欢迎你" + user.getUsername();
            }
            System.out.println(msg);
  
            os.write(msg.getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

 网络编程

ip地址与主机名

    C类地址(192.0.0.0-223.255.255.0):192.168.0.0~192.168.255.255
      
InetAddress类    无构造方法 getLocalHost获取本地ip getByName获取网络主机名

基于tcp:Socket(客户端)和Server Socket(服务器端)
    ServerSocket.accept():获取客户端socket

Socket通信模型
    进行网络通信是,Socket需要借助数据流来完成数据的传递工作
Socket类
    两个Socket类的构造方法及其含义
    Socket socket=new Socker("localhost",8800)
    ServerSocket serverSocket = new ServerSocket(9000);
    
    socket.getOutputStream();
    os.write

    1.建立连接
    2.打开Socket关联的输入输出流
    3.数据流中读写信息
    4.关闭所有的数据流和Socket
ServerSocket类的accept()方法有何用处:获取客户端socket

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.net.InetAddress;
import java.net.UnknownHostException;
  
public class TestAddress {
    public static void main(String[] args) throws UnknownHostException {
        //InetAddress:IP地址包装类
        InetAddress localHost = InetAddress.getLocalHost();
        System.out.println(localHost.getHostAddress());//ip地址
        System.out.println(localHost.getHostName());//主机名
        //得到网络主机名
        InetAddress address = InetAddress.getByName("www.baidu.com");
        System.out.println(address.getHostAddress());
        System.out.println(address.getHostName());
    }
}  

 UDP

基于UDP协议的Socket编程
    1.利用DatagramSocket发送数据包
    2.利用DatagramPacket对象封装数据包
    3.利用DataGramPacket处理数据包
    4.利用DataGramPacket接收数据包
    
    建立发送端,接收端
    创建数据
    建立数据包
    调用Socket的发送接收方法
    关闭SOcket
    发送端与接收端是两个独立运行的程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;
  
public class UDPSend {//发送端
  
    public static void main(String[] args) throws IOException {
        DatagramSocket ds = new DatagramSocket();
        byte[] msg = "最新的邮件来了。。。。".getBytes(StandardCharsets.UTF_8);
        //创建数据包,即将发送出去的数据包,发送的内容,收获的ip,端口号,
        DatagramPacket dp = new DatagramPacket(msg, 0, msg.length, InetAddress.getByName("localhost"), 9000);
        //发送数据
        ds.send(dp);
        //关闭资源:socket
        ds.close();
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
  
public class UDPReceive {
    public static void main(String[] args) throws IOException {//接收端
        //1.创建DatagramSocket
        DatagramSocket ds = new DatagramSocket(9000);
        //2.创建Packet
        byte[] temp = new byte[1024];
        DatagramPacket dp = new DatagramPacket(temp, temp.length);
        //3.接收数据
        ds.receive(dp);
        //发送方的主机名
        String hostName = dp.getAddress().getHostName();
        //发送方的端口号
        int port = dp.getPort();
        System.out.println("发送方的主机名是"+hostName+"发送方的端口号是"+port);
        byte[] bytes = dp.getData();//获取接收到的内容
        String msg=new String(bytes,0, dp.getLength());
        System.out.println("发送过来的信息是:"+msg);
        //4.关闭资源
        ds.close();
    }
}

 DOM文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE students SYSTEM "student.dtd">
<students>
    <student id="1">
        <name>王同</name>
        <class>java</class>
        <score>89</score>
    </student>
    <student id="2">
        <name>李佳</name>
        <class>sql</class>
        <score>58</score>
    </student>
    <student id="3">
        <name>李白</name>
        <class>python</class>
        <score>90</score>
    </student>
</students>

 

1
2
3
4
5
6
<!ELEMENT students (student+)>
<!ELEMENT student (name,class,score)>
<!ATTLIST student id CDATA #IMPLIED>
<!ELEMENT name (#PCDATA)>
<!ELEMENT class (#PCDATA)>
<!ELEMENT score (#PCDATA)>

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class TestXML {
    public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException {
        //1.得到document
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
        //2.解析和加载xml文件到内存中去
        Document document = documentBuilder.parse("student.xml");
        //3.返回文档中的所有子节点
        NodeList nodeList = document.getChildNodes();
        Node root = nodeList.item(nodeList.getLength() - 1);
        System.out.println("root:" + root.getNodeName());//students
        //4.再查找他的子节点
        NodeList childNodes = root.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node item = childNodes.item(i);
            if ("student".equals(item.getNodeName())) {
                NodeList nodes = item.getChildNodes();
                for (int j = 0; j < nodes.getLength(); j++) {
                    Node node = nodes.item(j);
                    if ("name".equals(node.getNodeName())) {
                        System.out.println("name:" + node.getTextContent());
                    } else if ("class".equals(node.getNodeName())) {
                        System.out.println("class:" + node.getTextContent());
                    } else if ("score".equals(node.getNodeName())) {
                        System.out.println("score:" + node.getTextContent());
                    }
                }
            }
        }
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
  
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.FileOutputStream;
import java.io.IOException;
  
public class UpdateXML {
    public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException, TransformerException {
        //使用DOM对XML文件进行数据修改
        //1.得到document
        DocumentBuilderFactory dbf;
        dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
        //解析和加载xml文件到内存中去
        Document document = documentBuilder.parse("student.xml");
        //1.删除某个节点
//        NodeList list = document.getElementsByTagName("student");
//        for (int i = 0; i < list.getLength(); i++) {
//            Element item = (Element)list.item(i);
//            //node:节点(文本节点),element:元素
//            //凡是元素都是节点,但是节点不一定都是元素,例如:一个单纯的回车也是节点
////            System.out.println(item.getAttribute("id"));
//            if ("2".equals(item.getAttribute("id"))){
//                item.getParentNode().removeChild(item);
//            }
//        }
  
  
        //2.添加节点
//        //student(name class score)
//        Element student = document.createElement("student");
//        student.setAttribute("id", "3");//设置属性值
//        //name
//        Element stuName = document.createElement("name");//创建节点
//        stuName.setTextContent("李白");//设置节点内容
//        student.appendChild(stuName);//添加节点
//        //class
//        Element stuClass = document.createElement("class");
//        stuClass.setTextContent("python");
//        student.appendChild(stuClass);
//        //score
//        Element stuScore = document.createElement("score");
//        stuScore.setTextContent("90");
//        student.appendChild(stuScore);
//        //找到根节点students
//        NodeList nodeList = document.getElementsByTagName("students");
//        Node students = nodeList.item(nodeList.getLength() - 1);
//        students.appendChild(student);
  
        //修改:李白-》李清照
        //1.查找节点
        NodeList student3 = document.getElementsByTagName("student");
        for (int i = 0; i < student3.getLength(); i++) {
            Element item = (Element)student3.item(i);
            if ("3".equals(item.getAttribute("id"))){
                Node name = item.getElementsByTagName("name").item(0);
                //2.修改节点内容
                name.setTextContent("李清照");
                break;
            }
        }
  
  
        //保存成XML文件
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        DOMSource domSource = new DOMSource(document);
        // 设置编码类型
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        StreamResult result = new StreamResult(new FileOutputStream("student.xml"));
        // 把DOM树转换为XML文件
        transformer.transform(domSource, result);
  
    }
}

 

DOM4j

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<books>
    <book id="book1">
        <name>三国演义</name>
        <price>99.88</price>
    </book>
    <book id="book2">
        <name>西游记</name>
        <price>77.88</price>
    </book>
    <book id="book3">
        <name>李白的诗</name>
        <price>88.88</price>
    </book>
</books>

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
  
import java.util.Iterator;
import java.util.List;
  
public class TestDom01 {
    public static void main(String[] args) throws DocumentException {
        SAXReader saxReader = new SAXReader();
        Document doc = saxReader.read("books.xml");
        //得到根节点
        Element root = doc.getRootElement();
        System.out.println(root.getName());//root
        //遍历显示所有的数据
        List<Element> list = root.elements("book");
        for (Element book:list){
            Attribute id = book.attribute("id");
            System.out.println("id:"+id.getValue());
            //迭代器
            Iterator<Element> it = book.elementIterator();
            while (it.hasNext()){
                Element element = it.next();
                System.out.println(element.getName()+":"+element.getText());
            }
            System.out.println("----------------");
        }
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
  
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
  
public class TestDom02 {
    public static void main(String[] args) throws DocumentException, IOException {
        //需求:实现 删除 id="book3"这样的一个节点
        /*
        <book id="book">
        <name>李白的诗</name>
        <price>88.88</price>
        </book>
         */
        //解析xml文件
        SAXReader saxReader = new SAXReader();
        Document doc = saxReader.read("books.xml");
        //得到根节点
        Element root = doc.getRootElement();
        //找到相应的节点
        List<Element> bookList = root.elements("book");
        for (Element book:bookList){
            Attribute id = book.attribute("id");
            if ("book3".equals(id.getValue())){
                book.getParent().remove(book);//删除
            }
        }
        //保存到xml文件
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        XMLWriter writer = new XMLWriter(new FileWriter("books.xml"));
        writer.write(doc);
        writer.close();
        System.out.println("删除成功");
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import org.dom4j.*;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
  
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
  
public class TestDom03 {
    public static void main(String[] args) throws DocumentException, IOException {
        //需求:实现 新增节点
        /*
        <book id="book">
        <name>李白的诗</name>
        <price>88.88</price>
        </book>
         */
        //解析xml文件
        SAXReader saxReader = new SAXReader();
        Document doc = saxReader.read("books.xml");
        //得到根节点
        Element root = doc.getRootElement();
        //新增节点
        Element book = DocumentHelper.createElement("book");
        book.addAttribute("id", "book3");
  
        Element name = DocumentHelper.createElement("name");//创建节点
        name.setText("李白的诗");//设置属性
        book.add(name);//添加节点
  
        Element price = DocumentHelper.createElement("price");
        price.setText("88.88");
        book.add(price);
        root.add(book);
        //保存到xml文件
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        XMLWriter writer = new XMLWriter(new FileWriter("books.xml"));
        writer.write(doc);
        writer.close();
        System.out.println("新增成功");
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
  
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
  
public class TestDom04 {
    public static void main(String[] args) throws DocumentException, IOException {
        //需求 实现 修改 id="book3"这样的一个节点 李白的诗-》李清照的诗句2.外部类外部:StaticInnerClass.Inner inne
        SAXReader saxReader = new SAXReader();
        Document doc = saxReader.read("books.xml");
        //得到根节点
        Element root = doc.getRootElement();
        System.out.println(root.getName());//root
        //遍历所有的数据
        List<Element> list = root.elements("book");
        for (Element book : list) {
            //找到对应的节点
            if ("book3".equals(book.attribute("id").getValue())) {
                //迭代器
                Iterator<Element> it = book.elementIterator();
                while (it.hasNext()) {
                    Element element = it.next();
                    //找到要修改的文本
                    if ("李白的诗".equals(element.getText())) {
                        element.setText("李清照的诗");
                        System.out.println(element.getName() + ":" + element.getText());
                        break;
                    }
                }
                break;
            }
        }
        //保存到xml文件
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        XMLWriter writer = new XMLWriter(new FileWriter("books.xml"));
        writer.write(doc);
        writer.close();
        System.out.println("修改成功");
    }
}

 集合

2.外部类外部:StaticInnerClass.Inner inne

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import java.util.HashSet;
import java.util.Set;
  
public class Worker {
    private String name;//姓名
    private int age;//年龄
    private int salary;//收入
  
    public Worker(String name, int age, int salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }
  
    @Override
    public String toString() {
        return "Worker{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                '}';
    }
  
    @Override
    public int hashCode() {
        // TODO Auto-generated method stub
        return this.name.hashCode() + age + salary;
    }
  
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (this.getClass() != obj.getClass()) {
            return false;
        }
        Worker obj2 = (Worker) obj;
  
        if (this.name.equals(obj2.name) && this.age == obj2.age && this.salary == obj2.salary) {
            return true;
        }
        return false;
    }
  
    public static void main(String[] args) {
        Set<Worker> hashSet = new HashSet<>();
        //hashcode作为索引或者说是唯一标识
        hashSet.add(new Worker("zhang3", 18, 1500));
        hashSet.add(new Worker("li4", 18, 1500));
        hashSet.add(new Worker("wang5", 18, 1600));
        hashSet.add(new Worker("zhao6", 18, 2000));
        hashSet.add(new Worker("zhao6", 18, 2000));
  
        for (Worker worker : hashSet) {
            System.out.println(worker);
        }
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
  
public class Worker implements Comparable {
    private String name;//姓名
    private int age;//年龄
    private int salary;//收入
  
    public Worker(String name, int age, int salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }
  
    public String getName() {
        return name;
    }
  
    public void setName(String name) {
        this.name = name;
    }
  
    public int getAge() {
        return age;
    }
  
    public void setAge(int age) {
        this.age = age;
    }
  
    public int getSalary() {
        return salary;
    }
  
    public void setSalary(int salary) {
        this.salary = salary;
    }
  
    @Override
    public String toString() {
        return "Worker{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                '}';
    }
  
    @Override
    public int compareTo(Object o) {
        if (this == o) {
            return 0;
        } else {
            if (o instanceof Worker) {
                Worker worker = (Worker) o;
                if (this.age != worker.getAge()) {
                    return this.age - worker.getAge();
                } else if (this.salary != worker.getSalary()) {
                    return  this.salary-worker.getSalary();
                } else {
                    return this.name.compareTo(worker.getName());
                }
            } else {
                try {
                    throw new Exception("只能比较Worker对象");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return 0;
    }
  
    public static void main(String[] args) {
        TreeSet<Worker> set = new TreeSet<>();
  
        set.add(new Worker("zhang3", 18, 1500));
        set.add(new Worker("li4", 18, 1500));
        set.add(new Worker("wang5", 18, 1600));
        set.add(new Worker("zhao6", 17, 2000));
  
  
        for (Worker worker : set) {
            System.out.print(worker.getName()+"\t");
        }
    }
}

 

posted @   霖霖的信箱  阅读(72)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示