不会改变原始对象的方法

reverse函数,作用:排序 使用小技巧 判断string是否相等可以使用equals来进行判断。 判断string是否是空字符串可以用isBlank()进行判断 对于超大的整数加减使用对应的函数进行操作,比如加,使用add函数 参考bignum.java 因为math类的构造方法是private修饰,所以无法建立实例 使用 String.charAt( index ) 方法,返回在index位置的char字符。(返回值:char ) 使用 String.toCharArray( ) 方法,将String 转化为 字符串数组。(返回值:char[] ) 1 变量赋值和类型转换 重点强制转换类型和类型转换 对于赋值的情况。在左右两边不同精度的情况下,如果精度不同需要强制转换类型。 比如 float y=3.14 在定义这个float类型的数据的时候精度就不匹配, 最好的情况是:float y=3.14f;这个样子设置的就是单精度数据,不需要考虑强制转换类型 提升: 对于将字符串转换成带有符号的int型,应该指的是正负号这种 调用Integer.parseInt(s),s值得是字符串 2 scanner 提升 重点对于scanner.nextLine()去除新行的理解
scanner.next()默认输入的是字符 scanner.nextLine(),将整行文本进行读取,在下次扫描器开始扫描之前的时候整行是为空的,在用户输入之后才会重新开始扫描对应的那一行 scanner.nextInt(),在扫描该行之后,下一次扫描的行中包含换行符,这个样子容易导致下一行如果是用nextLine()则无法进行自动扫描。随机生成数的时候使用nextint()可能生成负数 本质:nextline一次性扫描整行文本,如果是nextint则是只扫描到数字即停止,不包括代表终止的换行符,那么下一次留下的就有一个换行符 对于如果处理用户主动输入的最前面换行符不会导致scanner的全局扫描失败或者停止扫描 每次使用完扫描器记得关闭 3 运算表达式 提升: 特殊/,向下取整,对于除法,其实是返回的数据是正常运算的结果,但最后呈现出来结果取决了存储变量的类型!如果没有春初变量取决于除数和被除数谁的数据类型等级更高了 对于上行说的可以用向上和向下取整可以数学类的向上取整解决,比如:System.out.println(Math.round(11.6/3)); 4 gui界面 基础知识: 使用swing框架 导入import javax.swing.JOptionPane; 消息弹出框使用直接JOptionPane.showMessageDialog(null, "你的年龄是:" + age); 输入框使用直接JOptionPane.showInputDialog("请输入你的姓名"); 5 Math类 基础知识: 向下取整 Math.floor 向上取整 Math.ceil 四舍五入 Math.round 计算平方 Math.sqrt 提升: 6 Randmon类: 基础知识: 生成的浮点数的大小只能在0-1之间 生成的整数可以人为限制比如随机生成1-6的数字比如下行所示 random.nextInt(6)+1,如果不限制从1开始的话,默认是0 随机生成布尔值 7 if else 语句 提升: else只会匹配最近的if语句 else if是建立在最近的if语句不成立的情况下再次进行判断 8 switch 语句 基础知识: 提升: 如果每个case处理完只会没有break,那么则会一旦匹配成功一个case后面的语句也会执行,这个样子就会导致判断失败 其实switch循环只是通过break跳出了穷举循环和拥有对应的出错机制,一旦匹配成功减少次数罢了,如果for循环和while循环都是一样的条件判断循环,不是简单的数值循环其实这样三者的差距不大,唯一差距就是出错对应机制。 9 数组 提升: 对于string类数组查找一个值方式:1 Arrays.asList(str).contains() 2 使用set.contains() 3 使用for循环 10 String类和方法: 函数: indexOf(str):用来检测是否含有检测的字符串 toLowerCase():用来将字母全部小写化 replaceAll(regx,newstr):将所有的检测对应的字符串替换成新的字符串 charAt(index),查看具体的某个index下标的值 substring(indexnum,endnum),如果只有一个下标数字,则从下标数字到结尾,如果有两个包含从下标数字到结束下标之前,不包含结束下标的值 提升 string的好兄弟,stringbuilder 负责拼接和处理字符串的类,但他是可变的 对stringbuilder操作的方法,会返回this自用,这个样子可以一直使用下去,对String进行构造,而且对它进行修改是不会建立新string对象参考stringBuilder.java 11 包装类 就是基本原始数据类型的细分之后的类 提升: 可以赋值为null 提供了一系列的方法常用的有:parseInt(String s)、tostring()、valueOf(String s)、equals( object object)、i.compareto(integer anotherIntger) 集合中不允许放基本数据类型,只能放包装类! 缺点:由于每个值分别包装在对象中,所以ArrayList的效率远远低于int[]数组。(应该用其构造小型集合,其原因是程序员操作的方便性要比执行效率更加重要) 12 arrayList: 重点!!! 基础知识: 创建对象 ArrayList<String> food= new ArrayList<String>(); 获取arraylist的长度使用.size() 向arrarylist添加元素使用add()函数 修改arraylist元素使用set函数food.size(); 删除元素remove(1) 清空arraylist使用clear() 建立二维arraylist ArrayList<ArrayList<String>> shop=new ArrayList<>(); 向二维列表添加一维列表只需要使用add函数即可 提升: 13 foreach: 基础知识: for (String i : animals)类似与for animal in animals 参考foreach.java 提升: foreach 增加强的for循环,灵活性较低,但可读性较高使用方便,循环次数更少 14 方法/函数: 15 方法重载: 提升 区分方法的方式是通过方法签名即由方法名字和方法参数组成,看参数类型也可区分方法 16 static 关键字 类中静态运行代码块 17 printf 基础知识: 对于控制输出可以考虑是由flags -:代表右对齐 +:代表数字的正负号,这个也要占一位 .1:代表精确到小数位一位 数字:代表多少位数 0:代表前面空的位置用0来填充 提升: 运算时候的优先级为.1》+-》-》数字》0 num is:3.157num is:+0000001000.000 System.out.printf("num is:%0+15.3f",(double)1000); 18 final关键字: 基础知识: try-catch是否执行都会进行的代码 提升:定义常量,如果是对象,只要引用地址不变就可以。同理es6语法的const定义符一样。 final类不能被继承,即不能有子类,final方法不能被子类重写 19 list结合子类特点: Arraylist:底层数据结构是数组,查询速度快,增删速度慢 有序,可重复 linkedList:底层数据结构是链表,查询慢,增删快 set 元素不重复,无序 hashset:数据结构是哈希表,允许元素为null,保证元素唯一性(通过equals和hashcode方法保证) linkedList :具有可预测的迭代次序,保证元素有序。元素的存储顺序和取出舒徐顺序是一致的。哈希表保证元素的唯一性 treeSet:重写compareto方法,实现comparable接口 map: 使用key-value存储方式 具体的实现类:hashmap 获取所有的key集合:map.keySet() Set 获取所有的value集合 map.values Collection 获取键值对的集合entryset

面向对象编程

1 构造函数:只有在构建对象实例的时候调用的函数,方便构建不同属性的对象实例,为指定对象实例添加属性的时候记得添加this关键字,可以重载 2 作用域 这个部分也可也看作全局变量和局部变量的区别 3 字符串方法:在每次调用println的时候都在隐式调用tostring方法!!!对于tostring方法的重载,如果是在该方法中重新进行了对该实例的修改,则返回的还是地址而不是更改之后的内容 4 对象数组,为类将一个对象数组并填充对象进去即可 Food [] register={food1,food2,food3}; 5 static关键字 不管是类还是方法变量,如果定义是静态类则该类的所有实例和该类公用变量和方法,如果是方法、变量则,所有类和实例必须共享这个方法变量且最终值所有实例一致,最好调用的时候以类来调用而不是实例 6 继承 子类使用extends继承父类的变量和方法,方法不包括父类的构造方法。子类在继承的时候会继承父类无参的构造函数并且在子类生成实例的时候会调用一下父类的无参构造函数再去调用子类的对应参数参构造方法!!! 7 方法重写 子列和父类的方法名字相同则实例是哪个类的对象就调用哪个类方法。 8 super关键字 子类使用super关键字调用父类的被覆盖或者重写的方法,super() 9 abstract关键字 抽象类不可以实例化但可以有子类,抽象类可以有实例方法,抽象方法必须被子类覆盖重写且无法直接调用抽象方法,抽象方法不可以被private和static修饰!!! 10 修饰符 默认修饰符只对同一个文件夹下的类可见,public修饰符对同一个项目下的所有文件夹所有类都是可见的(前提要导入对应的类或者包),private只能被该类和在该类中建立的实例对象访问。!!!同一包内,普通类或子类都可以访问父类的protected方法;protect修饰符:不同包内,在子类中创建子类对象可以访问父类的protected方法;不同包内,在子类中创建父类对象不能访问父类的protected方法;不同包内,在子类中创建另一个子类的对象不能访问公共父类的protected方法;父类protected方法加上static修饰符,子类可以直接访问父类的protected方法。 11 封装:对于private这种修饰符修饰的属性需要进行设置对应的set函数和get函数 12 对象复制 如果是地址复制,则可以直接使用对象赋值给对象即是浅层拷贝。如果需要深层拷贝,可以自己写一个函数进行调用拷贝对象的set和get属性函数进行相应的赋值。 13 接口 一个类可以有多个接口。接口方法可以不是abstract方法,但子类必须重写覆盖接口方法,子类要使用修饰符修饰重写的方法,default方法,实现该接口的子类可以不必重写该方法,接口的静态方法只可以被接口调用,不可以被是实现类调用(防止实现多个接口的时候实现类不知道调用的是哪个接口的静态方法),对于接口中有两个及以上的方法包含相同的代码段时使用private方法实现代码复用java9的特性。pravite,static,default不影响lambda表达式,默认方法可以调用私有的静态方法和非静态方法,但静态方法只能调用私有的静态方法 14 多态 将一个父类多个子类实例的对同一个事件的不同反应 15 动态多态性 用父类建立对象,但该对象实例是子类的实例对象。像是做一件事情父子和他的儿子们不同的做法 16 异常 final不管是否捕捉错误都会执行 17 文件类。使用方法大致一致。不管文件对象的创造的时候要给文件类一个路径。 18 文件读取类,在使用读取文件类的时候记得加一个try-catch语句!!!!。 19 audio类,如果没有让进程暂时停止的代码,则在加载音频的时候Java不会播放声音
20 读取图片 ImageIcon imgLogo=new ImageIcon("./logo.png"); imgLogo.getImage() 22 GUI界面 设置标题: setTitle 设置logo setTitle 设置内容板背景颜色 getContentPane().setBackground(new ColorUIResource(0, 255, 0)); 设置正常关闭 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 设置不可调整大小 setResizable(false); 设置可见 setVisible(true);

23 方法链,一次调用多个方法而不是一行一行的调用 23 枚举,一组有序常量并且类似于类的对象,在java编译和运行时候无法改变,不同的是对于操作类似常量的常见实例对象时不进行传参,而是进行在建立类似常量的类型和构建函数处理。 参考enumerable.java 24 hashmap 25 泛型 对于不同类型的对象进行同一事件的解决。比如说人和熊猫都要吃饭,人是一顿,熊猫是多少根竹子。参考thing.java,泛型定义单词不一样。 26 序列化,反序列化 前者将对象转换成字节流,后者将字节流换成对象,子类也可以进行序列化,对于静态属性字段不可以序列化,它不是对象。对于transient修饰符的字段不进行编译 (版本序列)UUID唯一序列化号码 自定义 private final static long serialVersionUID=1;参考serialization.java文件 序列化过程 // 进行序列化的五个步骤 // 1 你的对象应该实现连接Serializable接口 // 2 进行导入Serializable // 3 建立一个文件输出流 // 4 建立一个对象输出流 // 5 进行将对象进行写入对象输出流 // 6 关闭对象输出流,关闭文件输出流 反序列话的步骤 // 1 给需要编辑的类进行连接Serializable接口,建立一个对象但不要实例化!! // 2 导入Serializable // 3 实现文件输入流 FileInputStream fileIn=new FileInputStream("路径"); // 4 实现对象输入流 ObjectInputStream objIn=new ObjectInputStream(fileIn); // 5 进行读对象文件流 user=(Users) objIn.readObject(); // 6 关闭文件输入流和对象输入流objIn.close(); fileIn.close(); 27 计时器 需要实例化一个timer对象并实例化,再实例化一个timetask对象,再timetask对象的基础上重写run函数, 使用Calendar.getInstance()不仅能获取当前的时间,还能指定需要获取的时间点,在项目应用中达到定时的作用。参考setTime.java,停止计时器使用time.cancle(); 28 内部类。内部类可以访问容器类的变量,对自定义的监听器事件特别有用 29 线程 设置线程是守护线程,守护线程一般都是低优先级线程,用来进行垃圾回收的线程 30 多线程 对于多线程中线程之间是相互独立的,即时mian线程出错也不会影响到用户线程,如果除了main线程以外全是精灵线程则mian线程出错会直接退出报错 31 生成可运行jar包,自己百度 32 机密otp 33 string类对象的最重要的特点不可变,string类存储字符的数据是private修饰的,string的length是方法不是属性。 34 File类: listFiles()返回file类的对象数组 list()返回string的对象数组 35 lamda表达式: 使用前提: 1有一个接口,2接口有且仅有一个抽象方法3 必须有上下文环境 简略使用: 只有一个参数或者多个参数类型一致可以省略类型声明,不可以只省略一个 只有参数一个,可以省略圆 括号,只有一个语句可以省略大括号,如果有return也要省略掉 lambda和匿名内部类的区别:匿名内部类可以被使用所有的重写方法和不同参数还可以是具体类,而lambda表达式只能接受接口参数且有其仅有一个抽象方法,方法引用符 :: 可推导的就是可以省略的 36方法引用: 类方法引用: 实例: fun(Integer::parseInt);参考yinyong.java lambda表达式被类方法应用替代时,它的形式参数全部传递给静态方法作为参数 lambda表达式被对象的实例方法替代时,它的形式参数全部传递给该方法作为参数 lambda表达式在被类的实例方法替代的时候,一个参数作为调用者,后面的参数全部传递给该方法作为参数 lambda表达式在被构造器替代的时候,它的形式参数全部传递给构造器作为参数 37函数式接口: 标记接口是函数式接口@FunctionalInterface, 特点:有且仅有一个抽象方法 函数式接口作为返回值,参考comparatorDemo.java 常用的函数式接口: 1 Predicate接口:T get(),该方法不需要参数,他会按照某种实现逻辑(lambda)返回一个数据 2 Function接口: void accept(T t):对指定的参数执行此操作,default andThen方法。返回一个组合的Consumer。一次执行此操作,然后进行after操作,泛型接口,两次连续操作只公用原始的的数据。不会套接上一个消费之后的数据 3 Supplier接口 泛型接口 boolean test(T t)对给定的参数进行判断,判断逻辑有lanmbda表达式实现,返回一个布尔值。default negate(T)返回一个逻辑的否定,对应逻辑非。 and(predicate other) 返回一个组合的判断,对应与,or(predicate other)返回一个组合的判断,对应或,and和or用法类似与consumer的andthen方法一样 4 Consumer接口 R,T apply(T t)将此函数应用于给定的参数,default<V>funtion andThen(function after)返回一个组合函数,首先将该函数用于输入,将after函数应用于结果,Funtino<T,R>接口通常用于对参数进行处理,转换(处理逻辑由lambda表达式实现)返回一个新的值,function的andthen是对同一数据依次进行操作,即第二次的参数数据是第一次的结果 38 stream流的生成方式 1 生成流:通过数据源生成流 list.stream() 对collection体系可以直接使用.stream()生成流 对map体系间接生成流 Map<String,Integer> hashmap=new HashMap<String,Integer>(); Stream<String> key_stream = hashmap.keySet().stream(); Stream<Integer> values_stream = hashmap.values().stream(); Stream<Map.Entry<String, Integer>> stream = hashmap.entrySet().stream(); 对数组可以通过stream接口的静态方法of(T 。。。。。values)生成流 Stream<Integer> a2 = Stream.of(11,15,35,85); 2 中间操作:一个流后面可以跟随零个或者多个中间操作,其目的是打开流并进行某种的数据过滤/映射,然后返回一个新的流,交给下一个操作使用 filter() skip:从流中跳过n个参数返回后面的参数 limit:限制流返回多少个参数 filter:进行数据过滤 distinct:去重,根据equals方法去重 static concat(stream1,stream2)静态方法,将两个流合并起来 sort():自然排序 sort(Comparactor cp)自定义比较器排序 map()返回给定函数应用于此流元素的结果组成的流 mapToInt ()返回一个IntStream其中包含给定函数应用于此流的元素的结果,返回int类型的流,用于求和 3 终结操作:一个流只能有一个终结操作,执行此操作后该流无法被操作,foreach()count() foreach()对最终每个参数进行操作例如输出这种 count()统计多少个参数 4 收集流 R collect(Collector collector)该方法是参数一个Collector接口 Collectors工具类提供具体的收集方法 静态方法:toList(),toSet(),toMap(),分别把收集的元素转换成list,set,map 39映射: 类加载: 在程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过类的加载,类的连接,类的初始化这三个不走来对类进行初始化,如果不出现意外情况,jvm会连续完成这三个不走。有时候把这三个步骤统称为类加载或者类初始化 具体 类加载:class文件读入内存并为之创建一个java.lang.class对象生成一个java.lang.class对象(任何类在被使用时都是这样建立java.lang.class对象) 类的连接: 验证阶段:用于检验被加载类是否由正确的内部结构,并和其他类协调一致,准备阶段:为类的类变量分配内存并设置默认初始化值,解析阶段:将类的二进制数据中的符号引用替换成直接引用 类的初始化:主要对类变量进行初始化 类的初始化步骤: 1 如果该类还没有连接和加载,则程序先加载后连接父类 2 如果该类的父类没有被加载,则先去初始化父类 3 如果类中含有初始化语句,系统依次执行这些初始化语句 注意: 在执行第二个步骤的时候,系统对直接父类的初始化步骤也是顿寻初始化步骤1-3 类的初始化时机:直接使用java.exe命令来运行某个主类,使用反射方式强制创建某个类或者接口对应的java.lang.class对象。调用类的类方法或者创建类的实例或者访问类的类变量或者接口的类变量,或者为类变量复制,初始化某个类的子类 JVM的类加载机制: 1 全盘负责:当一个类加载器来加载某个class时,该class所以来的和引用的其他的class也将由该类加载器负责载入,除非显示使用另外一个类加载器来载入 2 父类委托:就是当一个类加载器负责加载某个class时,先让父类加载器驶入加载class,只有父类加载器无法加载该类时才尝试从自己的类路径来加载该类, 3 缓存机制:保证所有加载过的class都会被缓存,当程序需要使用某个class对象时,类加载器先从缓存区搜索该class,只由当缓存区不存在该class对象时,系统才会读取该类对应的二进制数据,并将其转换成class对象,存储到纯存取 Java运行时具有以下内置类加载器: . (祖宗加载器)Bootstrap类加载器。它是虚拟机的内置类加载器,通常表示为null,并且没有父null。 (父类加载器)Platform class loader。平台类加载器可以看到所有平台炎,可以将其用作classLoader实例的父classioader。平台类包括由平台类加载器或其祖先定义的Java SE平台API,其实现类和JDK特定的运行时类。 为了允许对定义到平台类加载器的模块进行升级/覆盖,并且升级后的模块读取定义到除了平台类加戟器及其祖先之外的类加戟器的摸块,则平台类加载器可能必须委派给其他类加载器例如应用程序类加载器。换句话说,除了平台类加载器及其祖先之外,定义为类加载器的命名模块中的类可能对平台类加载器是可见的。 . (子类加载器)System class loader。它也被称为应用程序英加载器,与平台类加载器不同。系统类加载器通常用于定义应用程序类路径,模块路径和JDK特定工具上的类。平台类加载器是所有平台类对其可见的系统类加载器的父级或祖先。 ClassLoader中的两个方法: static ClassLoader getSystemClassLoader():返回用于委派的系统类加载器 ClassLoader getParent():返回父类加载器进行委派 40 反射: 概述:在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象,调用的方法一种机制。由于这种动态性可以极大的增强程序的灵活性,程序不用在编译期就完成确定,在运行期任然可以扩展 获取class类的对象的三种方式:第一种使用类的class属性获取class类型的对象,第二种调用对象的getclass方法,返回该对象所属类对应的class对象 使用class类的静态方法forName(String className),该方法需要传入字符串参数,该字符串参数的值是某个类的全路径也就是完整把包名的路径 反射建立对象的流程:参考反射包 1 获取class对象 2 获取构造方法的对象 3 使用newInstance建立对象 获取一个构造方法getConstructors去掉s,括号中的参数是为了区分取走那个一个构造方法,getDeclaredConstructor同理 获取所有的构造方法 getConstructors只获取由public修饰符的构造方法,不访问private和默认修饰符的构造方法而这个getDeclaredConstructors可以获取所有的构造方法 ,Constructor<?> con = c.getDeclaredConstructor(String.class); 暴力反射:构造方法对象调用newInstance方法设置为true,即使是private修饰的构造方法也可以创建对象,成员变量同样也是 class类中获取成员变量的方法:主要参考获取构造构造方法对象 getFields:返回所有公共成员的变量的对象的数组,不包含父类的private字段 getDeclaredFields:返回所有成员变量的对象的数组,不包含父类的private字段 getField(String name):获取一个公共成员变量的对象 getDeclaredField(String name):获取一个公共成员变量的对象 Class类中用于获取成员方法的方法 Method getMethods():返回所有公共成员方法对象的数组,包括继承的方法 Method[]getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的方法 Method getMethod(String name, Class<?> ... parameterTypes):返回单个公共成员方法对象 Method getDeclaredMethed(String name, Class<?> ... parameterTypes):返回单个成员方法对象 41 模块化: 进行模块化的原因:防止jvm加载整个JRE环境 1.2模块的基本使用 模块的基本使用步骤 创建模块(按照以前的讲解方式创建模块,创建包,创建类,定义方法) 为了体现模块的使用,我们创建2个模块。一个是myOne,一个是myTwo 在模块的src目录下新建一个名为module-info.java的描述性文件,该文件专门定义模块名 访 问权限,模块依赖等信 描述性文件中使用模块导出和模块依赖来进行配置并使用 模块中所有未导出的包都是模块私有的,他们是不能在模块之外被访问的在myOne这个模块下的描述性文件中配置模块导出 模块导出格式: exports包名; 一个模块要访问其他的模块,必须明确指定依赖哪些模块,未明确指定依赖的模块不能访问 在myTwo这个模块下的描述性文件中配置模块依赖 模块依赖格式: requires模块名;

网络编程:

java为网络编程提供的类:InetAdress类 Socket sk=new Socket("127.0.0.1",12345);//实现127.0.0.1:12345发送数据 练习:发送udp报文,接收udp报文: // 1 建立一个udp的java类 DatagramSocket udp_send1=new DatagramSocket(); // 构造一个数据包并发送数据 DatagramPacket dp1=new DatagramPacket("luyuhan".getBytes(StandardCharsets.UTF_8), "luyuhan".getBytes(StandardCharsets.UTF_8).length, InetAddress.getByName("DESKTOP-FGLB2SS"), 10086); // 进行发送对应的报文类对象 udp_send1.send(dp1); // 关闭此数据报的对象 udp_send1.close(); 在udp通信中接收方如何解决正确获取数据长度? 在byte数组转换string类型的时候是使用数据报文的长度 String data_str=new String(data,0,dp_receive.getLength()); // 创建一个DatagramSocket类对象并绑定端口号用来接收数据 DatagramSocket udp_receive=new DatagramSocket(10086); // 构建一个数据包类对象用来接收数据报 byte[] content=new byte[1024]; DatagramPacket dp_receive=new DatagramPacket(content,content.length); udp_receive.receive(dp_receive); // 将数据报文转换成可看懂的数据 byte [] data= dp_receive.getData(); System.out.println(data.length); String data_str=new String(data,0,dp_receive.getLength()); System.out.println("内容:\n"+data_str); // 关闭此数据报的套接字 udp_receive.close(); tcp报文: 注意客户端的输出流指定是socket实例对象的输出流 注意服务器端创建的套接字是ScoketServer.accept方法建立的 发送数据: // 建立客户端的套接字对象 // 获取输出流,写数据, // 释放资源 Socket sk=new Socket("127.0.0.1",5051); OutputStream os= sk.getOutputStream(); os.write("tcp,我来了".getBytes(StandardCharsets.UTF_8)); os.close(); sk.close(); 接收数据: // 第一建立tcp服务器 // 第二创建获取输入流读取数据 // 第三 释放资源 ServerSocket server =new ServerSocket(12345); Socket s=server.accept(); InputStream is=s.getInputStream(); byte[] content=new byte[1024]; // 获取实际报文长度 // int len=is.read(content); String data=new String(content,0,is.read(content)); System.out.println("消息:"+data); is.close(); server.close();