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" ); } } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端