17.网络编程、反射

package com.atguigu.java2;

import java.net.InetAddress;
import java.net.UnknownHostException;

/*
一、网络编程中两个主要的问题:
1.定位网络上一台或多台主机:定位主机上的特定应用
2.找到主机后,可靠高效地进行数据传输

二、网络编程中两要素
1.提供具体的ip以及端口号
2.提供网络通信协议:TCP/IP参考模型:应用层、传输层、网络层、物理+数据链路层

IP和端口号
在java中使用InetAddress类代表IP
IP分类 :Ipv4 和IPv6
域名: www.baidu.com
本地回路地址:127.0.0.1 对应 localhost

端口号标识正在计算机上运行的进程

传输控制协议TCP协议
用户数据报协议UDP
 */
public class InterAddressTest {
    public static void main(String[] args) {
        try {
            InetAddress inet = InetAddress.getByName("192.168.10.14");


        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
}

TCP

package com.atguigu.java2;

import org.junit.Test;

import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/*
TCP网络编程
练习:客户端发送文件给服务器,服务器端保存到本地,
并返回”发送成功“给客户端,并关闭相应连接
 */
public class TCPTest {
    @Test
    public void clinet(){
        Socket socket = null;
        OutputStream os = null;
        FileInputStream fis = null;
        InputStream is = null;
        ByteArrayOutputStream baos =null;
        try {
            //1.
            socket = new Socket(InetAddress.getByName("127.0.0.1"), 9988);
            //2
            os = socket.getOutputStream();
            //
            fis = new FileInputStream(new File("timg.jpg"));
            //
            byte[] buffer = new byte[1024];
            int len;
            while((len = fis.read(buffer)) != -1) {
                os.write(buffer,0,len);
            }
            //关闭数据的输出
            socket.shutdownOutput();

            //接受来自服务器端信息,并显示到控制台
             is = socket.getInputStream();
             baos = new ByteArrayOutputStream();
            byte[] buffer1 = new byte[20];
            int len1 ;
            while((len1 = is.read(buffer1))!=-1){
                baos.write(buffer1,0,len1);
            }
            System.out.println(baos.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //5.关闭流操作
            try {
                baos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    @Test
    public void server(){
        ServerSocket ss = null;
        Socket socket = null;
        InputStream is = null;
        FileOutputStream fos = null;
        OutputStream os = null;
        try {
            //1
            ss = new ServerSocket(9988);
            //2
            socket = ss.accept();
            //3
            is = socket.getInputStream();
            //4
            fos = new FileOutputStream(new File("longmao.jpg"));
            byte[] buffer = new byte[1024];
            int len;
            while((len = is.read(buffer))!=-1){
                fos.write(buffer,0,len);
            }
            os = socket.getOutputStream();
            os.write("你好,图片已收到".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                ss.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

UDP

package com.atguigu.java2;

import org.junit.Test;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/*
UDP的网络编程
 */
public class UDPTest {
    //发送端
    @Test
    public void sender() throws IOException {
        DatagramSocket socket = new DatagramSocket();
        String str= "UDP方式发送信息";
        byte[] data = str.getBytes();
        InetAddress inet = InetAddress.getLocalHost();
        DatagramPacket packet = new DatagramPacket(data,0,data.length,inet,9090);
        socket.send(packet);

        socket.close();

    }

    //接受端
    @Test
    public void receiver() throws IOException {
        DatagramSocket socket = new DatagramSocket(9090);
        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()));
        socket.close();
    }
}

 URL

package com.atguigu.java2;
import java.net.MalformedURLException;
import java.net.URL;
/*
URL编程
1.URL:统一资源定位符,对应着互联网的某一资源的地址
2.格式:
http://localhost:8080/hello.txt?username=sun
协议  主机名   端口号  资源地址  参数列表
 */
public class URLTest {
    public static void main(String[] args) {
        try {
            URL url = new URL("https://baike.baidu.com/item/URL%E6%A0%BC%E5%BC%8F/10056474?fr=aladdin");
            System.out.println(url.getAuthority());
            System.out.println(url.getProtocol());
            System.out.println(url.getHost());
            //……
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }
}

反射

package java3;

public class Person {
    private String name;
    public int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public Person(String name) {
        this.name = name;
    }

    public void show(){
        System.out.println("这是一个人");
    }
    private String showNation(String nation){
        return "国籍时"+nation;

    }
    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;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

创建运行时类的对象

package java3;
/*
反射:动态语言的关键,
动态语言:在运行时代码可以根据某些条件改变自身结构

通过反射创建对应的运行时类的对象
 */
import org.junit.Test;
public class NewInstanceTest {
    @Test
    public void test() throws Exception {
        Class clazz = Person.class;
        /*newInstance() : 调用此方法调用运行时类的对象,即person的对象,内部调用空参构造器

         在javabean 中要求提供一个public的空参构造器,
         1.便于通过反射,创建运行类的对象
         2.便于子类继承此运行时类,默认调用super(),保证父类有此构造器
        */
        Object o = clazz.newInstance();
        System.out.println(o);//Person{name='null', age=0}
    }
}
package java3;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectionTest {
    //反射之前对person类的操作
    @Test
    public void test1() {
        //1.创建person的构造器
        Person p1 = new Person("tom", 12);
        //2.通过对象调用属性和方法
        p1.age = 18;
        System.out.println(p1.toString());
        p1.show();
        //person类外部,不可以通过person类的对象调用私有结构,比如:name、showNation
    }

    //反射之后
    @Test
    public void test2() throws Exception {
        //1.通过反射创建person类的对象
        Class<Person> clazz = Person.class;
        Constructor<Person> cons = clazz.getConstructor(String.class, int.class);

        Person p = cons.newInstance("tom", 12);

        //2.通过反射,调用person指定的属性
        Field age = clazz.getDeclaredField("age");
        age.set(p, 10);
        System.out.println(p.toString());//Person{name='tom', age=10}

        //3.通过反射,调用person指定的方法
        Method show = clazz.getMethod("show");
        show.invoke(p);//这是一个人

        //通过反射是可以覅用person类的私有结构
        Constructor<Person> cons1 = clazz.getDeclaredConstructor(String.class);
        cons1.setAccessible(true);
        Person p1 = cons1.newInstance("jerry");
        System.out.println(p1.toString());//Person{name='jerry', age=0}

        Field name = clazz.getDeclaredField("name");
        name.setAccessible(true);
        name.set(p1,"hanmeimei");
        System.out.println(p1.toString());//Person{name='hanmeimei', age=0}

        Method showNation = clazz.getDeclaredMethod("showNation", String.class);
        showNation.setAccessible(true);
        String s =(String)  showNation.invoke(p1, "中国");
        System.out.println(s);//国籍时中国
    }
    /*
    关于java.lang.Class类的理解
    1.类的加载过程
        程序在经过javac.exe命令以后,会生成一个或多个字节码文件。
        使用java.exe命令对某个字节码文件进行解析运行。相当于将某个字节码文件加载到内存,
        此过程就称为类的加载。加载到内存中的类,称为运行时类,此运行时类,就作为Class的一个实例

      2.  Class的实例就对应着一个运行时类

      3.加载到内存中的运行类,会缓存一定的时间,在此时间之内,可以同过不同的方式类获取Class的实例
     */
    
    /*
      获取Class的实例的方式(前三种需要掌握),第三种方式频率最高
     */
    @Test
    public void test3() throws ClassNotFoundException {
        //方式一:调用运行时类的属性:.class
        Class<Person> clazz1 = Person.class;
        System.out.println(clazz1);//class java3.Person
        //方式二:通过运行类的对象:调用getClass()
        Person p1 = new Person();
        Class clazz2 = p1.getClass();
        System.out.println(clazz2);//class java3.Person
        //方式三:调用Class的静态方法:forName(String classPath)
        Class clazz3 = Class.forName("java3.Person");
        System.out.println(clazz3);

        System.out.println(clazz1 == clazz2);//true
        System.out.println(clazz1 == clazz3);//true

        //方式四:使用类的加载器ClassLoader
        ClassLoader classLoader = ReflectionTest.class.getClassLoader();
        Class clazz4 = classLoader.loadClass("java3.Person");
        System.out.println(clazz1 == clazz4);//true
    }

}
package java4;

import java3.Person;
import org.junit.Test;

import java.lang.reflect.*;

/*
获取当前运行时类的属性结构
 */
public class OtherTest {
    @Test
    public void test(){
        Class clazz = Person.class;
        //了解
        //获取属性结构
        //getFields():获取当前运行时类及其父类中声明为public的属性
        //getMethods()
        Field[] fields = clazz.getFields();
        for(Field f : fields){
            System.out.println(f);//public int java3.Person.age
        }
        //getDeclaredFields():获取当前运行时类中所有属性,不包含父类中的属性
        //getDeclaredMethods():
        Field[] declaredFields = clazz.getDeclaredFields();
        for(Field f1: declaredFields){
            System.out.println(f1);//private java.lang.String java3.Person.name
                                  // public int java3.Person.age
        }
    }
    //掌握
    @Test
    public void test2() throws Exception {
        Class clazz = Person.class;
        //getConstructors():获取当前运行时类中申明为public的构造器
        Constructor[] constructor = clazz.getConstructors();
        for(Constructor c :constructor){
            System.out.println(c);//public java3.Person(java.lang.String)
                                  //public java3.Person(java.lang.String,int)
                                  //public java3.Person()
        }
        //getDeclaredConstructors():运行时类中所有构造器
        Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
        for(Constructor c1 :declaredConstructors){
            System.out.println(c1);
        }
    }

    @Test
    public void test3(){
        Class clazz = Person.class;
        //getSuperclass():获取运行时类的父类
        //getGenericSuperclass():获取运行时类的带泛型的父类
        Class superclass = clazz.getSuperclass();
    }
    //获取运行时类的带泛型的父类的泛型
    @Test
    public void test4(){
        Class<Person> clazz = Person.class;
        Type genericSuperclass = clazz.getGenericSuperclass();
        ParameterizedType paramType = (ParameterizedType)genericSuperclass;
        //获取泛型类型
        Type[] actualTypeArguments = paramType.getActualTypeArguments();
        for (Type t :actualTypeArguments){
            System.out.println(t);
        }
    }
    //掌握:调用指定运行时类的结构:属性、方法、构造器
    @Test
    public void test5() throws Exception {
        Class clazz = Person.class;
        //创建运行时类的对象
        Person p = (Person)clazz.newInstance();
        //获取指定的属性getField 只能获取public的属性不常用,一般用getDeclaredField
        Field age = clazz.getField("age");
        //设置当前属性值 set():参数1:指明设置那个对象的属性,参数二:属性的设值多少
        age.set(p,18);
        //获取当前属性值 get():参数1:指明获取那个对象的属性
        int page =(int) age.get(p);
        System.out.println(page);


        Field name = clazz.getDeclaredField("name");
        //setAccessible(true):保证当前属性是 可访问的
        name.setAccessible(true);
        name.set(p,"tom");
        System.out.println(name.get(p));//tom
    }
    //掌握 操作指定方法
    @Test
    public void test6() throws Exception {
        Class clazz = Person.class;
        Person p = (Person)clazz.newInstance();
        /*获取指定的某个方法
        * getDeclaredMethod():参数1:指明获取的方法的名称,参数二:获取指定形参列表
        *invoke():参数1:方法的调用着,参数二:给方法形参赋值的实参
        *       invoke()的返回值,即为对应类中调用的方法的返回值
        */
        Method showNation = clazz.getDeclaredMethod("showNation", String.class);
        showNation.setAccessible(true);
        System.out.println(showNation.invoke(p, "CHN")); //国籍时CHN

        //如何调用静态方法
        Method showdesc = clazz.getDeclaredMethod("showdesc");
        showdesc.setAccessible(true);
        showdesc.invoke(Person.class);
    }

}

 

posted @ 2021-05-31 08:02  孫sun  阅读(38)  评论(0编辑  收藏  举报