自学内容网 自学内容网

木舟0基础学习Java的第二十一天(网络编程,反射)

网络编程

三要素:1.IP地址 2.端口 3.协议

 InetAddress互联网协议 (IP) 地址

 封装了IP地址的类

用法:
public static void main(String[] args){
        //获取IP地址
        try {
            InetAddress ia=InetAddress.getByName("www.baidu.com");
            System.out.println(ia);//www.baidu.com/110.242.68.3
            //返回本地域名
            System.out.println(ia.getHostName());//www.baidu.com
            //返回IP地址
            System.out.println(ia.getHostAddress());//110.242.68.3
            System.out.println(ia.getCanonicalHostName());//110.242.68.4
            //获取本机地址
            InetAddress localHost = ia.getLocalHost();
            System.out.println(localHost);
        } catch (UnknownHostException e) {
            throw new RuntimeException(e);
        }
    }

URL路径

用法:
 public static void main(String[] args) {
        //URL路径
        try {
            URL url=new URL("https://www.baidu.com:80/index.html#muzhou");
            System.out.println("协议:"+url.getProtocol());//协议:https
            System.out.println("域名:"+url.getHost());//域名:www.baidu.com
            System.out.println("端口:"+url.getPort());//端口:80
            System.out.println("资源:"+url.getFile());//资源:/index.html
            System.out.println("锚点:"+url.getRef());//锚点:muzhou
            System.out.println("相对路径:"+url.getPath());//相对路径:/index.html
            System.out.println("参数:"+url.getQuery());//null
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }
    }

常用端口:

3306 mysql

1521 oracle

80 web

8080 tomcat

4000 QQ

2425 飞秋feiQ

协议:

UDP协议:

用户数据 面向连接 数据安全 速度快 区分客户端和服务端

(例子:相当于发短信 不论对方是否在线 是否能接收到)

Socket通信(套接字):

网络上具有唯一标识的IP地址和端口号组合在一起  才能构成唯一能识别的标识符套接字

通信的两端都有Socket

网络通信其实就是Socket间的通信

数据在Socket中通过IO流传输

案例:UDP传输多线程
//(服务端)接收
public class Reciver extends Thread {
    public void run(){
        //建立码头
        DatagramSocket s=null;
        try {
            //指定端口号9999
            s=new DatagramSocket(9999);
            //货轮
            byte[] b=new byte[1024];
            //集装箱接受数据
            DatagramPacket p=new DatagramPacket(b,1024);
            while(true){
                //将数据装载到集装箱中
                s.receive(p);
                //获取数据来源的地址
                InetAddress ip=p.getAddress();
                String msg=new String(b);
                System.out.println("从"+ip+"发送过来"+msg);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally{
            s.close();
        }
    }

}
//(客户端)发送
public class Sender extends Thread {
    public void run(){
        //创建码头
        DatagramSocket s=null;
        while(true){
            try {
                s=new DatagramSocket();
                //准备备货物
                Scanner sc=new Scanner(System.in);
                System.out.println("请客户端输入:");
                String msg=sc.next();
                //创建货轮
                byte[] b=msg.getBytes();
                //获取客户地址
                InetAddress ip=InetAddress.getByName("127.0.0.1");
                //将货物装入集装箱
                DatagramPacket p=new DatagramPacket(b,0,b.length,ip,9999);
                //发送
                s.send(p);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }finally{
                s.close();
            }
        }
    }
}

 //测试
 public static void main(String[] args) {
        Reciver r=new Reciver();
        r.start();
        Sender s=new Sender();
        s.start();
    }

(重点)TCP协议:

传输控制 面向连接(三次握手) 数据安全 速度略慢 分为客户端和服务段

(例子1:打电话 呼叫 接听 数据传输)(例子2:网站访问:客户端发送请求 连接服务器 数据传输)

案例:TCP传输多线程

public class Sender extends Thread{
    public void run(){
        ServerSocket ss=null;
        BufferedReader br=null;
        try {
            //创建服务端的套接字
           ss=new ServerSocket(8888);
            //阻塞
            Socket socket=ss.accept();
            //读取客户端的流
            InputStream in=socket.getInputStream();
           br=new BufferedReader(new InputStreamReader(in));
            while(true){
                String msg=br.readLine();
                System.out.println("客户端发来:"+msg);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally{
            if(br!=null){
                try {
                    br.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
public class Client extends Thread {
    OutputStream out=null;
    BufferedWriter bw=null;
    public void run(){
        try {
            //定位
            Socket s=new Socket("127.0.0.1",8888);
            //发送
            out=s.getOutputStream();
            bw=new BufferedWriter(new OutputStreamWriter(out));
            Scanner sc=new Scanner(System.in);
            while(true){
                System.out.println("请客户端输入:");
                String str=sc.next();
                bw.write(str);
                bw.newLine();
                bw.flush();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally{
            if(bw!=null){
                try {
                    bw.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
public class Test_Client {
    public static void main(String[] args) {
        Client c=new Client();
        c.start();
    }
}
public class Test_Sender {
    public static void main(String[] args) {
        Sender s=new Sender();
        s.start();
    }
}

反射 (解剖 类)

对于任意一个类 都能知道这个类中的所有属性和方法

对于任意一个对象 都能够调用它任意的方法和属性

动态获取的信息以及动态调用对象的方法 称为java的反射机制

类的加载:

类的加载概述:当程序要使用某个类时,如果该类没有加载到内存中 系统将通过加载,连接,初始化三步实现对这个类进行初始化 

加载:将class文件读入内存 并为之创建一个class对象 任何类被使用时系统都会创建一个class对象

连接:

验证:是否有正确的内部结构 并和其他类协调一致 

准备:负责为类的静态成员分配内存 并赋值 默认值

解析:将类的二进制数据中的符号引用替换为直接引用

初始化

平时使用的

类加载器(classLoader):负责将.class文件加载到内存中 并为之生成对应的class对象

类加载器分为:根类加载器 扩展类加载器 系统类加载器

字节码加载时机:

创建类的实例(new)

访问类的静态变量或者为静态变量赋值

调用类的静态方法 使用反射方式强制创建某个类或接口对应的class对象

初始化某个类的子类 直接使用java.exe命令运行某个主类

获取字节码文件

三种方式获取字节码文件

  //三种方式获取字节码文件
        //第一种
        Class c1=Class.forName("com.muzhou.lesson.Person");
        //第二种
        Class c2=Person.class;
        //第三种
        Person p=new Person();
        Class c3=p.getClass();
        //验证三种方法取出的字节码文件是否相同
        System.out.println(c1==c2);//true
        System.out.println(c2==c3);//true

反射创建无参构造和有参构造

第一种

 //获取反射无参构造和有参构造创建
    public static void main(String[] args) throws Exception {
        //Class类的.newInstance()是使用该类的无参构造方法创建对象
        //如果一个类没有无参构造 就不能这么创建 会报错 InstantiationException
        Class clazz=Class.forName("com.muzhou.lesson.clazz.Person");

        //通过无参构造创建对象
       /* Person p =(Person) clazz.newInstance();
        System.out.println(p);//Person{name='null', age=0}*/

        //获取有参构造  没有无参构造创建对象
        //clazz.getConstructor(String.class,int.class);//String.class,int.class要与Person类中的属性对应
        Constructor c = clazz.getConstructor(String.class, int.class);
        //通过有参构造创建对象
        Person p=(Person)c.newInstance("张三",23);
        System.out.println(p);//Person{name='张三', age=23}

第二种

 //反射其实就是在分解class对象
        Class<Person> clazz=Person.class;
        //这个过期了 Person p1 =clazz.newInstance();
        //现在使用.getDeclaredConstructor().newInstance();创建一个无参构造器对象 再用对象创建实例
        Person p1 = clazz.getDeclaredConstructor().newInstance();
        p1.setName("张三");
        p1.setAge(23);
        System.out.println(p1);

        Constructor<Person> c = clazz.getDeclaredConstructor(String.class, int.class);
        Person p2 =c.newInstance("李四", 24);
        p2.eat();
        p2.eat(10);
        System.out.println(p2);

反射获取成员变量(如果是私有的就用暴力反射)

   Class clazz=Class.forName("com.muzhou.lesson.clazz.Person");
        Constructor c = clazz.getConstructor(String.class, int.class);
        Person p =(Person)c.newInstance("张三", 23);

        //clazz.getFields("name");可以获取到类中指定的字段(必须是可见的public)
      /*  Field f = clazz.getFields("name");
        f.set(p,"李四");*/

        //暴力反射
        Field f = clazz.getDeclaredField("name");
        //在这一步去除私有权限 变成public
        f.setAccessible(true);
        f.set(p,"李四");
        System.out.println(p);

反射获取方法

 //反射获取方法
        Class clazz=Class.forName("com.muzhou.lesson.clazz.Person");
        Constructor c = clazz.getConstructor(String.class, int.class);
        Person p =(Person) c.newInstance("张三", 23);
        //通过clazz获取Method 返回的是Method 获取eat方法
        Method m1 = clazz.getMethod("eat");//eat不用加()
        m1.invoke(p);

        //获取带参数的方法
        Method m2 = clazz.getMethod("eat", int.class);
        m2.invoke(p,10);

反射获取所有属性


        Class<Person> clazz=Person.class;
        //获取所有成员变量
        Field[] fields =clazz.getDeclaredFields();
        System.out.println(fields.length);//2
        for (Field f : fields) {
            System.out.println(f.getName()+"----"+f.getAnnotatedType());
        }
        //获取所有构造
        Constructor<?>[] c = clazz.getDeclaredConstructors();
        for (Constructor cs : c) {
            System.out.println(cs);
        }
        //获取所有方法
        Method[] m = clazz.getDeclaredMethods();
        for (Method method : m) {
            System.out.println( method.getName()+"返回类型"+method.getGenericReturnType()+"方法中形式参数"+
                    method.getGenericParameterTypes());

        }


原文地址:https://blog.csdn.net/tzh525/article/details/140565118

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!