JAVA笔记

108 阅读23分钟

extends -->继承 Instanceof -->多态里面的比较是否new 的对象为他 abstract -->抽象类 final --> 不可修改,最终的 如果在类前面加那么表示此类不可以被继承 static -->静态类

接口: interface -->生成接口 implements -->实现接口

封装等级: private -->局部 pubilc -->外包也可以 protected -->不适应同一个工程

其他东西: Objgct -->所有的父类 Math.random() -->随机数生成 Arrays.sort(b); -->快速排序 n.equals( ) -->比较方法 Pattern.matches(s2, identityCard) -->正则表达式判断,前面有个放正则后面一个放string类型

路径调包: package -->路径(自己的路径) import -->调用包(别的包路径)

异常: Throwable -->比下面的这个异常等级更高的异常类 Exception -->异常类所继承的是Throwable try catch finally -->常用的异常处理方式 throws -->在函数后面加把错误导给调用它的类 throw -->使用来抛异常 如 new WoshiyigeYichang("我是个异常"); 但是得重写父类(记得写序列化) 自定义异常得继承Exception try (f1;f2) { } catch (Exception e) { }--> 关闭f1,f2流操作 可以省略(finally) -->java 9 写法可以吧需要关闭的流的名字写在try语句里面 然后会实行自动关闭流操作f1(不能修改指定因为他声明成final了)

多线程:多线程的四种创建方式 extends Thread -->使用继承的方式调用多线程 implements Runnable -->使用多线程需要继承的接口 ,比Thread好用 implements Callable -->比Runnable接口强大的接口 支持返回值,泛型类,异常 ExecutorService x1= Executors.newFixedThreadPool(2);-->创建一个指定大小的线程池

多线程:常用方法 1.xc.start(); -->启动该线程 2.xc.setName("线程1:"); -->给线程起名字 3.Thread.currentThread() -->当前进程 4.Thread.currentThread().setName("主线程:");-->给main主线程命名 5.getNAme(); -->获取当前线程名字 6.Thread.currentThread().getName() -->输出当前线程名称 7.run(); 通常重写好用

阻塞线程的4种方式: 8.xc.join(); -->当i为20的时候只有执行完调用线程 xc的线程的时候才会执行 需要try/catch 环绕 让自己堵塞执行xc线程完成之后在执行自己 9.yield(); -->如果满足此条件释放当前执行权力 10.sleep(500); -->如果满足此条件就让他500秒之后再运行 需要try/catch 环绕 11.this.stop(); -->强制性结束进程 1.wait(); -->睡眠此线程

多线程:优先级: Thread.MAX_PRIORITY -->设置线程优先级为最高 Thread.NORM_PRIORITY -->设置线程优先级为中 Thread.MIN_PRIORITY -->设置线程优先级为最低 输出优先级: setPriority() -->输入线程优先级: xc2.setPriority() xc2.getPriority() -->输出线程优先级 xc2.getPriority()

多线程:唤醒 { -->都是在同步代码块里面操作 让此线程不能执行 1.wait(); -->睡眠此线程 2.wait(long timout)-->睡眠指i定时间后唤醒此线程 3.notify() -->唤醒优先级高的线程 4.notifyAll() -->唤醒所有睡眠线程

  • 注此类是在Obgect类中调用的 ,slepp是在Thread中调用的 }

多线程:线程安全 1.Synchronized(this) -->同步锁 用来防止线程不安全问题 如果使用static那调用的就是 当前对象.class 2.ReentrantLock re= new ReentrantLock() --> 类 锁定此方法让该方法进来的只有一个线程 { re.lock();锁定 re.unlock();解锁方法 需要try环绕 }

多线程:线程池 ExecutorService 和 Executors工具类 ExecutorService 真正的接口 常见子类ThreadPoolExecutor

创建线程池: ExecutorService x1= Executors.newFixedThreadPool(2);-->创建一个指定大小的线程池 ExecutorService x3= Executors.newCachedThreadPool();-->创建一个可能需要创建的线程池 ExecutorService x4= Executors.newSingleThreadExecutor();-->创建一个只有一个线程的线程池 ExecutorService x5= Executors.newScheduledThreadPool(100);-->创建一个线程池,它可安排在给定延迟后运行命令或者定期执

使用线程池: x1.execute(Runnable r1); -->执行Runnable接口的线程池 x1.submit(Callable c1);-->开启线程3 execute适应于 Callable接口

x1.shutdown(); -->关闭线程池的连接

String 类:

s1.length() -->比较字符长度 String s2=s1.substring(2); -->取出从第2个之后开始的东西 从0开始取出>> 及解决方法 int i=s2.indexOf("查找我")); -->返回索引到的位置从 下标0开始 找不到返回-1 s1.contains(s91); -->判断s9中是否包含s91的这个字符串 true s1.equalsIgnoreCase(s61) -->比较是否相同但是不区分大小写

s1.isEmpty() -->判断字符是否为空 s1.charAt(2) -->找string类型的第2位 从第0位开始 s1.trim() -->去掉前面的空格和后面的空格 s1.toLowerCase() -->大写转小写 s1.toUpperCase() -->小写转大写 s1.compareTo(s71) -->比较有多少个数不相同 s7所有加起来的ask码值-s71所有加起来的ask码值 返回askll码值 s1.replace('山','中'); -->吧所有的山换成中支持换多个字符 int i=s1.lastIndexOf("ab"); -->返向查找 正则 boolean u1=u2.matches("0512-\d{7,8}"); -->判断是否是0512开头并且有7位 返回true或者flase

String 类:string转char: String u2="abc123"; char[] u21=u2.toCharArray(); -->吧所有的值全部复制给u21数组 System.out.println(u21[0]);

String 类:char转string char[] u31=new char[]{'1','2','a','b','c'}; String u3=new String(u31); -->吧char类型所有东西全部放到string类型里面 System.out.println(u3);

String转成int类型: String s1="123"; int zhuAn=Integer.parseInt(s1); -->parseint 类型转换

int转string类型: int a=10; String ab=String.valueOf(a);

string类型转换成byte数组: String s1="转换byte"; byte[] b1=s1.getBytes();

StringBuffer和StringBuider 的函数:区别

String -->一个不可改变的字符序列 Stringbuffer -->是一个线程安全的线程安全 因为线程安全所以效率低一些 一般用来用存在多线程使用 StringBuilder -->是一个线程不安全的 所以效率高一点 一般用来写不存在多线程的时候用

1.如果需要频繁修改就不用string 2.stringbuffer和stringbuilder默认数组长度都是16 vait【16】 3.如果超过16那么扩容的是原来的2倍+2,并且吧该值赋值给新的数组 4. String和StringBuffer和StringBuider在java9新特性中采用的是byte[]数组,在java9以前采用的都是char[]类型数组(节约空间) 5.如果已知长度推荐使用 StringBuilder(40);以免后面还需要重新赋值给新的数组

Stringbuffer和StringBuider 的函数: 增删改查

    StringBuilder st=new StringBuilder(40); -->设置默认初始值字符串长度为40
    st.append("niha1o");         -->追加在后面添加  增
    st.delete(0,2);             -->删除下标0到2的值  删
    st.replace(4,6,"a");       -->在4,7位置改成a  改
    st.charAt(12);            -->查询位置为12后面的
    st.insert(12,"你好");     --> 在12位后插入数据 插
    st.length();            -->返回数组里面存储的值的长度  不是数组的长度
    st.setCharAt(4,'a');   --> 在4的位置修改一个字符
    int a=st.indexOf("iha1o"); -->查找这句话在此文章中出现的位置返回下标i所在的位置

System类: String win=System.getProperty("oc.name"); -->win7 String admin=System.getProperty("user.name");-->Administrator System.exit(0); -->也可以强制性结束 如果为1就是异常退出

BIginttegr类: 如果数很大比如高精度就使用BigInteger类 BigInteger b1=new BigInteger("123") -->需要计算的数 b1.add(BigInteger val) -->返回和 b1.subtract(BigInteger val) -->返回差 b1.multiply(BigInteger val) -->返回积 b1.devide(BigInteger val) -->返回商 b1.remainder(BigInteger val) -->返回余 b1.compareTo(BigInteger val) --> 返回比较结果,返回值是1、-1、0,分别表示当前大整数对象大于、小于或等于参数指定的大整数。 b1.abs() --> 返回绝对值 b1.pow(int exponent) -->返回当前大整数对象的n次幂。 b1.toString() -->返回十进制的字符串表示 b1.String toString(int p)-->返回当前对象以p进制的字符串表示。

枚举类: enum -->定义枚举类 可以实现接口但是不可以继承父类 { 枚举类_1(1,2), 枚举类_2(10,20); -->逗号继续,分号结束 都是 public static final 类型的 } 枚举类使用 mei=枚举类使用.枚举类_1; -->调用枚举类 枚举类使用[] a=枚举类使用.values(); -->使用values类枚举类 枚举类使用 a1=枚举类使用.valueOf("枚举类_1"); -->通过名字查找对象

集合Collection接口: Collection c1=new ArrayList(); -->创建一个可变数组 List和set都属于Collection接口里面的 *Map属于另一个接口 Collection有一个工具类叫Collections 比他多一个s 里面有提供很多方法如吧线程改成安全的

集合:ArrayList可变数组: List list1=new ArrayList(); -->底层数组 查询快 List li=new LinkedList(); -->底层链表 插入删除快 无序 -->Arraylist 初始化长度为10,后面长度不够<默认为扩容1.5倍> 同时将数组复制到新的数组中 条件允许开发中使用带参的构造器确认数组长度 -->8.0版本之后刚刚创建开始是 空{} 在add操作之后才开始创建 长度为10的操作 这样子可以节约内存 -->LinkedList无序可变数组 -->底层采用的是双向链表结构 频繁的插入和删除调用它最好 因为下面需要频繁的操作指针所以只需要添加不需要频繁修改 的话使用ArrayList比较快

添加插入: list1.add(a); -->添加 list.add(1,"我好"); -->在指定下标插入 list.addAll(list1);-->吧另一个可变数组添加到此数组后面 删除: list1.remove(2); -->移除指定下标 list1.remove("你好"); -->移除指定元素 list1.removeAll(coll);-->查找2个重复的如果相同就不输入相同的 修改: list1.set(1, "你好"); -->修改 指定坐标的值 查询: list1.get(1) -->查询下标为1对应的东西 int a= list1.indexOf("你好") -->查找"你好"对于的下标->如果不存在返回-1 int a=list.lastIndexOf("123"); -->查找"123"最后一次出现的位置->如果不存在返回-1 List l1=list.subList(0,3); -->获取下标0到3位置下的值 list1.retainAll(c2); -->查找相同的,输出出来并且修改完成之后list1就为相同的了 list1.removeAll(c1); -->查找2个重复的如果相同就不输入相同的[你好, 4] 并且修改完成之后list1就里面就存储2个相同的 转换: Object[] objects = list1.toArray(); -->集合转换成数组 List list= Arrays.asList(new Integer[]{123,123}); -->吧数组转换成集合

遍历1: iterator()-->遍历操作 每次调他都会返回迭代器开头 -> Iterator 迭代器,再次调用他将会吧指针返回到初始化位置0 { -> Iterator iterator = list.iterator(); -->集合的遍历迭代器为0 while(iterator.hasNext()) -->判断hasNext元素指针下一个是否有元素 { iterator = list1.iterator(); -->返回到指针开始 System.out.println(iterator.next()); -->输出元素 next 是指针下移 iterator.remove();-->删除元素 } } 遍历2: list1.forEach(System.out::println); -->新的遍历方法java8新特性 遍历3: for(Object O:list1) { System.out.println(O); }

集合:LinkedList List list=new LinkedList(); for (Object e:list) -->增强for循环 前面是类型后面是需要循环的值

Set接口: Set s1=new HashSet(); -->按照类型来排序 Set s1=new LinkedHashSet(); -->按照输入顺序排序 Set s1=new TreeSet(); -->按照输入顺序排序 ,根据第一个类型判别后面所有类型

< map = new HashMap<>()>底层调用了此 --> -->1.不可重复:是指地址值不可重复 如果有重复只输出一次, -->2.无序性不等于随机性 存储的数据在地址也中并非按照索引顺序添加的. -->3.底层采用链表加数组 通过哈希表 先通过计算哈希值判断位置然后找到数组位置 位置上如果没有值就直接放进去, -->如果有值哈希值相同就比较equas值, 如果值也相同就残忍抛弃,如果不相同就添加上用链表连接,下一个值进来的时候有会判断上一个和本值是否不一样如果不一样也放进来

Map接口:实现类 Map map1=new HashMap(); -->1 Map map2=new LinkedHashMap();-->2 Map map3=new TreeMap(); -->3 Map map3=new Hashtable();-->4 --废弃方法,古老实现类线程不安全 不可以存储null的key和value

<1>主要实现类,线程不安全,效率高,可以存储null的key和value ->底层采用数组加链表(java7) (java8)之后采用数组+链表+红黑树 <2>保证遍历map元素时key,按照顺序执行遍历,底层有(双向链表) ->对于频繁的遍历操作 效率高于HashMap <3>保证按照添加发的key——value 对于进行排序,实现排序遍历,底层使用(红黑树) <4>Properties 子类 常用来处理配置文件 底层key value都是string类型的

-->HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
-->HashMap 实现了 Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步。
-->HashMap 是无序的,即不会记录插入的顺序。
-->HashMap 继承于AbstractMap,实现了 Map、Cloneable、java.io.Serializable 接口。

Map接口:方法 添加: map1.put("AA",111);-->添加 删除: map1.remove("AA"); -->移除所对应的key和value 修改: map1.put("AA",444); -->如果key一样那么修改后面对于的值为444 查询: Object var=map1.remove("BB"); -->接收到BB所对应的value, 不存在放回null <删除> Object var=map1.get("AA"); -->返回key“AA”所对应的value,不存在返回null Object var=map1.size(); -->返回key“AA”所对应的长度

bool b=containsKey() 方法检查 hashMap 中是否存在指定的 key 对应的映射关系。 如果 hashMap 中是否存在指定的 key 对应的映射关系返回 true,否则返回 false。

-->遍历 Set set = map1.keySet(); -->对于的所有key值 Collection values = map1.values(); -->对应所有的value值 Set set2 = map1.entrySet();-->对应的所有的set和对应的vlue值

容器:Collections工具类 Collections.reverse(li); -->反转数组 Collections.sort(li); -->对集合进行自然排序 Object obj=Collections.max(li); -->返回元素中最大的值 Object obj=Collections.frequency(li,21); -->返回元素中21出现的次数

Collections.synchronizedXXXX(li)               -->返回一个线程安全的对象;
List list = Collections.synchronizedList(li); -->返回一个List安全对象
Set set=Collections.synchronizedSet(l2);     -->返回一个Set安全对象
Map map=Collections.synchronizedMap(l3);    -->返回一个Map安全对象

泛型: java 中泛型标记符: • E - Element (在集合中使用,因为集合中存放的是元素) • T - Type(Java 类) • K - Key(键) • V - Value(值) • N - Number(数值类型) • ? - 表示不确定的 java 类型 Fanxing fx=new Fanxing<>(); -->如果前面声明了类型后面可以不需要写 List<?> list=new ArrayList<>(); -->使用通配符的话就不能向其内部添加数据,只可以直接赋值进去 void 泛型方法 (E next) { } -->泛型方法,不太确认的类型就可以使用泛型方法 T t1[]= (T[]) new Object[10]; -->定义泛型数组 通配符: List<? extends l1子 > b1=null; --> 不可以比此类型大 但是可以等于此类型 <= List<? super l1父 > b2=null; --> 不可以比此类小 ,但是可以比此类范围大 >=

Json: JSONObject js=new JSONObject(); -->json格式 js.fluentPut("账号","123"); -->读取进去值,前面是名字后面是存储的值

    JSONObject js=new JSONObject().parseObject(js1); -->吧JSon格式放进去
    String a=js.getString("账号");    -->读取string类型的
    int a1=js.getIntValue("密码");    -->读取int类型的

IO流: { 文件的操作(常用函数): f1.getAbsolutePath();->获取绝对路径 f1.getPath(); ->获取相对路径 f1.getName(); ->获取名称 f1.getParent(); ->获取上层目录路径 无返回null f1.length(); ->获取文件长度(字节数) f1.lastModified();->获取最后修改时间,毫秒值

    Bool判断类型:
          f1.isDirectory(); ->判断是否为文件目录(就是里面还有值)
          f1.isFile();    -> 判断是否是文件
          f1.exists();    ->判断文件是否存在
          f1.canRead();   ->判断是否可读
          f1.canWrite();  ->判断是否可写
          f1.isHidden();  ->判断是否隐藏
    文件的创建与删除:
          f1.createNewFile();  ->创建文件如果此文件不存在了就返回true 注意是创建文件其他都是创建文件夹
          f1.mkdir();     ->创建文件夹如果文件夹存在就不创建
          f1.delete();    ->删除f1文件路径下的文件
          f2.mkdirs();    ->创建文件夹如果文件夹不存在就不创建 如果路径不存在就创造路径

   文件读写操作:
           f1.readLine(byte)  ->对文件进行写操作  (读入进的字符串)
           f1.read(byte)  ->对文件进行写操作  (读入进的字符串)
           bos.write(byte,0,leng); ->对文件进行读操作 (读入的字符串,从哪里开始,到哪里结束)
    获取文件:
          File f4=new File("D:java1");
          String[] list = f4.list(); ->获取该目录下的所有文件
          File[] file=f4.listFiles(); ->获取指定目录下的所有文件目录带c:-->

          FileSystemView fsv = FileSystemView.getFileSystemView();
          File com=fsv.getHomeDirectory();    ->获取桌面路径


    流的读取:int len;  byte[] by=new byte[1024]    while ((a1=b1.readLine())!=null)  { b2.write(by,0,len); } -->数据的读写代码

 *字符流(文本操作):
         FileReader f1=new FileReader("tt1.txt");  -->写出流
         FileWriter f2=new FileWriter("tt1.txt",true);
         -->第2个如果为true那么就是往后追加 如果为flase就覆盖着写 写出的时候不存在会自动创建  读入流

 *字节流(图片,视频操作):
         FileInputStream f3=new FileInputStream("tt1.txt");    -->字节写出
         FileOutputStream f4=new FileOutputStream("tt1.txt",true);  -->字节读入

 缓冲流(增加速度):
         BufferedReader b1=new BufferedReader(new FileReader(f1));
         -->缓冲写出流(文本文件)
         BufferedWriter b2=new BufferedWriter(new FileWriter(f2));
         -->缓冲读入流(文本文件)

         BufferedInputStream cin=new BufferedInputStream(new FileInputStream(f3));
          -->缓冲写出流 (图片,视频操作)
         BufferedOutputStream cout=new BufferedOutputStream(new FileOutputStream(f4));-->缓冲读入流 (图片,视频操作)

 转换流(字节转字符<——>字符转字节):
          InputStreamReader n1=new InputStreamReader(new FileInputStream(f3),"UTF-8");
          -->默认字符为系统自己设置 字节流-->字符流
          InputStreamReader cin=new InputStreamReader(new FileInputStream(f3),"utf-8");
          -->以utf-8的方式写出  字符流-->字节流
          OutputStreamWriter cout=new OutputStreamWriter(new FileOutputStream(f4),"gbk");
          -->以gbk的方式读入  字符流-->字节流

 可读可写的(RandomAccessFile)流:
            RandomAccessFile r1=new RandomAccessFile(new File("图9.jpg"),"r");
            -->只读的方式  写出文件
            RandomAccessFile r2=new RandomAccessFile(new File("图10.jpg"),"rw");
            -->可写出可读入的方式 读写文件
            RandomAccessFile r3=new RandomAccessFile(new File("f1.txt"),"rw");
            -->可读可写的方式 操作txt类型文件
          常用函数:
            r3.seek(3);-->吧指针移动读出位置的第3个地方
            r2.write("abcd".getBytes());
            -->覆盖操作写是从头开始覆盖 原来是 1235678wqert  覆盖前面之后操作完成;abcd5678wqert

    对象流(用于类的转换):
                基本数据类型是可序列号的
                如果想此类可以被序列化必须实现Serializable 或者Externalizable
                对于 static   transient 属性是无法序列号的   transient 关键字表示这个属性不想被序列化
                序列化,标识此类如果此类发生变化那么反序列号回来的时候还是可以通过此序列号值在还源回来
                如果没有此序列号如果此类改变了那么就还原回来就找不到此一样的类就会报异常

     序列化操作:
           ObjectOutputStream o1=new ObjectOutputStream(new FileOutputStream("D:\\untitled3\\src\\Demo\\java2\\lo流\\对象流,txt"));
             -->序列化操作
            o1.writeObject(new String("你好中国\n特别好啊"));-->吧对象序列化存储到文件里面
            o1.flush(); -->刷新操作
            o1.close(); -->关闭操作

     反序列化操作:
             ObjectInputStream o2=new ObjectInputStream(new FileInputStream("D:\\untitled3\\src\\Demo\\java2\\lo流\\对象流,txt"));
             -->反列化操作
                  Object a=o2.readObject();-->读取所有数据
                  String b=(String)a;    -->转换为string类型
                  o2.close();       -->关闭


 不可打开的文件类(ByteArrayOutputStream)流用于网络编程:
            ByteArrayOutputStream baos=new ByteArrayOutputStream(); -->用来写入字符和字节文件


 标准输入控制台(了解就行):
          InputStreamReader isr=new InputStreamReader(System.in);-->标准从键盘读入
          BufferedReader br=new BufferedReader(isr); -->流包起来
          String data= br.readLine();-->数据读出
         输出:
          FileOutputStream fos=new FileOutputStream(new File("ff2_xg.txt"));
          PrintStream ps=new PrintStream(fos,true);  -->true代表覆盖操作
          System.setOut(ps);   -->修改打印流吧打印出去的地方修改成输入到文件里面

   >>流操作最后都必须执行: f1.close -->流关闭操作

}

网络编程:TCP UDP URL {

InetAddress inet1=InetAddress.getByName("127.0.0.1");  -->写入ip地址  返回   /127.0.0.1
        InetAddress.getByName("www.baidu.com"); -->写入域名    返回:  www.baidu.com/112.80.248.76
        InetAddress.getByName("localhost");     -->写入本机    返回:  localhost/127.0.0.1 本机地址
        InetAddress.getLocalHost() ;            -->写入本机    返回:  dzqdb1 /192.168.159.1 我现在电脑所对应局域网中的ip地址和名字
        InetAddress.getByName("dzqdb1") ;       -->写入本机名字 返回:  dzqdb1 /192.168.159.1 通过名字查找ip地址
域名和名字(获取):
    System.out.println("5号的名字为:"+inet5.getHostName());      -->获取名字
    System.out.println("5号的ip地址为:"+inet5.getHostAddress()); -->获取ip地址
    sockt.getInetAddress().getHostAddress();->>获取传输过来的IP地址:



TCP网络编程(传输文字):三次握手,四处挥手保证数据的传输稳定性
    客户端:
     Socket socket=new Socket(InetAddress.getByName("127.0.0.1"),4444); -->传输进来服务端的ip地址和端口号
     OutputStream os = socket.getOutputStream();  -->传输字节读入流
     os.write("你好啊".getBytes());     -->数据传输到服务器  getBytes() 转换成byte字节流
     socket.shutdownOutput();        -->告知服务器我数据已经传输完了,不在输出数据了  不写此语句导致服务器端一直等待客户端做出回应
     socket.close();    -->关闭连接
     os.close();        -->关闭文件流

    服务端:
    ServerSocket ss = new ServerSocket(9999);-->自己服务器的地址
    Socket sockt=ss.accept(); -->(写出获取)接收来自客服端的sockt数据 有线程阻塞必须得等到数据传输进来之后才会往下执行
         InputStream is = sockt.getInputStream();  -->(读入)传输进来的数据
         System.out.println("收到了来自于"+sockt.getInetAddress().getHostAddress()");-->获取传输过来的ip地址
         ByteArrayOutputStream baos=new ByteArrayOutputStream();-->吧所有字符串都读取进来然后读取完成之后再拼接成一个字符串
          byte[] buff=new byte[5];
          int len;
         while((len= is.read(buff))!=-1)
         {
             baos.write(buff,0,len);
         }
        System.out.println(baos.toString());-->吧传输过来的字节流打印出来
            is.close();    -->读入关闭
            sockt.close(); -->关闭接收数据
            baos.close();  -->关闭流
            ss.close();    -->关闭服务器

TCP网络编程(传输图片.视频等):
      客户端:
       Socket socket=new Socket(InetAddress.getByName("127.0.0.1"),4444); -->服务端的ip地址,端口
       OutputStream out = socket.getOutputStream();-->输出流
       FileInputStream stream = new FileInputStream(new File("C:\\Users\\hbl\\Desktop\\lo流\\图9.jpg"));-->需要读取的文件
       byte[] by=new byte[1024];
       int len;
       while((len=stream.read(by))!=-1)
       {
           out.write(by,0,len);
       }
        socket.shutdownOutput();
        -->告知服务器我数据已经传输完了,不在输出数据了  不写此语句导致服务器端一直等待客户端做出回应
        -->关闭操作

    服务端:
      ServerSocket ss = new ServerSocket(9999);-->自己服务器的地址
      Socket sockt=ss.accept(); -->接收来自客服端的sockt数据
      InputStream is = sockt.getInputStream();  -->读入传输进来的数据 (图片和视频版)

      byte[] buff=new byte[5];
      int len;
      ByteArrayOutputStream baos=new ByteArrayOutputStream();
      -->吧所有字符串都读取进来然后读取完成之后再拼接成一个字符串

      while((len= is.read(buff))!=-1)
      {
          baos.write(buff,0,len);
      }
      System.out.println(baos.toString());-->输出
      -->关闭流操作


      服务端回应数据操作:
        回应数据(在代码后面写):
          OutputStream os=accept1.getOutputStream();
          os.write("数据我已经收到,非常好看!".getBytes());-->转换字节发送给服务器

       DatagramSocket socket=new DatagramSocket(); -->连接使用UDP方式



使用UDP网络格式发送数据:(不管对方有没有接收到都吧包发给对方)
    客户端:
        DatagramSocket socket=new DatagramSocket(9999); -->指定端口号
                byte[] buffer=new byte[100];
                DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length); -->接收数据
                socket.receive(packet);    -->等待数据传输过来接收数据
                System.out.println(new String(packet.getData(),0,packet.getLength()));
                                  -->第一个是数据,第2个是从哪里开始,第三个是数据的长度
                socket.close(); -->关闭操作


     服务端:
             DatagramSocket socket=new DatagramSocket(); -->连接使用UDP方式
              String str="我是以UDP方式发送的导弹";
              byte[] data=str.getBytes(); -->转换成字节流

              DatagramPacket packet=new DatagramPacket(data,0,data.length,InetAddress.getByName("127.0.0.1"),9999);
              --> 封装的数据包                             发送的文件/从哪开始发/到那结束发送   服务器ip地址、端口号

              socket.send(packet); -->发送数据包
              socket.close();-->关闭发送


使用URl网络格式发送数据:(从网站上面获取数据):
            URL url = new URL("http://www.baidu.com/gettf?name="张三"&password=“12345”);
            -->输入网站地址获取文件
             HttpURLConnection urlcon = (HttpURLConnection) url.openConnection();  -->转化为文本显示
             urlcon.connect();   -->获取连接
             InputStream is = urlcon.getInputStream();    -->获取网站里面的内容
             BufferedReader buffer = new BufferedReader(new InputStreamReader(is));  -->放入buffer里面

              while ((l = buffer.readLine()) != null) {  bs.append(l).append("\n");}  -->获取操作
              JSONObject ob=new JSONObject().parseObject(bs.toString());     -->转化为json格式
                String a=ob.getString("name");    -->获取name值

}

反射: { -->1.服务器运行起来之后不知道应该new那个类的时候就用反射,体验上动态性 -->2.反射和面向对象是否冲突了? 面向对象的私有化是告诉你这个方法我已经在我的类里面实现了就不需要你在调用他了, 封装性是解决到底建议你调什么样子的东西 反射是用来解决我能不能调的问题 -->3.反射可以是常用类型 int 也可以是数组(一维数组都是相同的class) 或者本身 或者void类型 接口,注解,enum枚举类型

创建反射的三种方式: 第一种: Class c1=Username.class ; -->找到位置 第二种: Username use=new Username(); Class c2=use.getClass(); -->通过构造器找到当前类位置 第三种: Class c3 = Class.forName("class Demo.java3.反射.Username");-->通过全名找到位置(这个方式用的多一点) 第四种: ClassLoader loa = Username.class.getClassLoader(); -->获取此类的类加载器 Class c4=loa.loadClass("class Demo.java3.反射.Username");-->产生进来

获取所有属性的类型以及修饰符: 1.Field[] fields = c1.getFields(); -->获取所有的public属性(继承了父类还会找父类的所有属性) 2.Field[] fields1 = c1.getDeclaredFields(); -->返回该类的所有属性(包括private属性的) 但不包含父类的属性

权限修饰符.数据.类型: Field[] fields = clazz.getDeclaredFields(); -->返回该类的所有属性(包括private属性的) 但不包含父类的属性 for(Field f:fields){ -->for循环 int i = f.getModifiers(); -->输出0,1,2,3,4这样子的 -->权限修饰符 String s = Modifier.toString(i);-->转换回来成普通类型的 -->private public Class type=f.getType() -->数据类型 String name = f.getName(); -->返回: name,age,id 变量名称 }

获取所有方法名: Method[] methods1 = c1.getDeclaredMethods();-->返回所在类的方法(所有权限的方法) 和类名称

获取:@注解 权限修饰符.方法名(参数类型1,形参名1).返回值类型
Method[] methods = c1.getDeclaredMethods();-->返回所在类的方法(所有权限的方法)
        <for(Method m1:methods){
Annotation[] annotations = m1.getAnnotations();  -->可能会有多个注解所以用数组
        <for (Annotation a1:annotations){
System.out.println("获取到的注解:"+a1);
}
System.out.println( "权限修饰符"+Modifier.toString (m1.getModifiers())+"            "
                    +"返回值类型:"+m1.getReturnType().getName()+"      "
                    +"方法名:"+m1.getName()-->方法名
                    );-->获取所有的方法的(public private)等权限修饰符  加返回值类型 方法名

Class[] types = m1.getParameterTypes(); -->获取里面的所有形参
for (Class c:types){
ystem.out.print("形参:"+c.getName()); -->输出
}
   /* 返回:
             形参:(形参:java.lang.String)
             权限修饰符public            返回值类型:int
             方法名:compareTo  (形参:java.lang.String)
             获取到的注解:@Demo.java3.反射.MyAnnotation(value="hello")

}-->结束循环

获取抛出的异常: Class[] ex= m1.getExceptionTypes(); -->获取抛出的异常 if(ex!=null&&ex.length!=0) -->如果为0或者为空就是啥也没有 { for(int i=0;i<ex.length;i++) { System.out.print(" "+"抛出的异常:"+ex[i].getName());-->抛出异常 } /* 抛出的异常:java.lang.Exception */ }

构造器(公有和所有的权限修饰符构造器): Constructor[] c1=c1.getConstructors(); -->获取当前运行时类中声明为public的构造器 Constructor[] c11=c1.getDeclaredConstructors(); -->获取当前运行时类中所有权限修饰符的构造器 -->返回为:private Demo.java3.反射.Person1(java.lang.String,int)

获取运行时代泛型的父类的泛型: Type type1 = c1.getGenericuperclass();-->获取运行时带泛型的父类 ParameterizedType theorized= (ParameterizedType) type1; -->获取运行时代泛型的父类的泛型 Type[] Actual = theorized.getActualTypeArguments();-->父类可能会有多个泛型所以是数组类型的

获取运行时的父类: Class aClass = c1.getSuperclass(); -->获取运行时的父类

获取运行时带泛型的父类(会用到): Type type = c1.getGenericuperclass();-->获取运行时带泛型的父类

    /*
     不带泛型的父类:class Demo.java3.反射.Creature
     获取时带泛型的父类:Demo.java3.反射.Creature<java.lang.String>
     运行时代泛型的父类的泛型:class java.lang.String
     */

获取运行时类的接口(会用到): Class[] interfaces = c1.getInterfaces(); -->获取运行时类的接口 Class[] interfaces1 = c1.getSuperclass().getInterfaces();-->获取运行时类的父类的接口

    /*
   运行时类的接口:interface :java.lang.Comparable
               interface :Demo.java3.反射.MyInterface
   父类的接口:interfaces1 java.io.Serializable
     */

获取运行时类所在的包位置: Package aPackage = c1.getPackage();-->获取运行时类所在的包位置 /* 运行时所在的包位置: package Demo.java3.反射 */

获取运行时类的注解: Annotation[] annotations = c1.getAnnotations();-->获取运行时类的注解 /* 运行时类的注解:@Demo.java3.反射. MyAnnotation(value="我是运行时类的注解") */

<--如何调用/获取 运行时类的(属性)(方法)(构造器)

获取指定的属性(支持私有)(修改.查看): 步骤1::Person1 obj = (Person1)c1.newInstance(); -->获取指定的构造器 步骤2::Field name = c1.getDeclaredField("name"); -->获取属性 步骤3::name.setAccessible(true); -->必须得实现为true这样子才给你调用私有 步骤4::name.set(instance,"你好");-->往里面放值 步骤5::Object o = name.get(instance);-->获取里面的值

使用方法(支持私有): bject o = c1.newInstance(); -->构造器调用空参构造器 Method show = c1.getDeclaredMethod("show", String.class); -->输入需要调用参数的方法(名称,和参数) show.setAccessible(true); -->保证方法是可访问私有的 Object o1 = show.invoke(o, "我是中国人"); --> invok 是调用里面的方法 第一个是类构造器,第二个是参数,如果有返回值就可以接收

调用构造器带参数的构造器(不通用): 一般使用不带参数的因为不适合 Constructor constructor = c1.getDeclaredConstructor(String.class); -->调用有参数的构造器 ,指明构造器的参数列表 constructor.setAccessible(true); -->保证能访问 Person1 instance = (Person1)constructor.newInstance("我爱我的国家 传输进去构造器的值"); -->调用一个参数的构造器 System.out.println(instance.toString()); -->输出属性有没有发生改变

}