0
点赞
收藏
分享

微信扫一扫

Java学习记录day13

路西法阁下 2022-04-02 阅读 101
java

文章目录

day13

对象流

对象序列化机制就是把内存中的Java对象转成与平台无关的二进制文件,从而可以进行持久化储存或者通过网络传输。

序列化:用ObjectOutputStream完成对象的保存

反序列化:用ObjectInputStream完成对象的读取

序列化的过程就是将java对象保存到硬盘中或者通过网络传输

//序列化
ObjectOutputStream oos = null;
try {
    oos = new ObjectOutputStream(new FileOutputStream("object.dat"));

    oos.writeObject("我爱北京天安门");
    oos.flush();
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    try {
    if(oos != null)
    oos.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
}

反序列的过程,将硬盘中或者通过网络传输获取到的对象转化为java对象

//反序列化
ObjectInputStream ois = null;
try {
        ois = new ObjectInputStream(new FileInputStream("object.dat"));

        Object obj = ois.readObject();
        String str = (String)obj;
        System.out.println(str);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } finally {
        if(ois != null) {
            try {
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    }
}

自定义序列化需要:

  1. 实现Serializable接口
  2. 当前类提供一个全局的常量:SerialVesionUID常量。 不给也行,接口会自动给一个常量,但反序列的时候可能会出错。
  3. 出来当前类需要实现Serializable接口外,其内部的属性 需要支持序列化

static和transient修饰的成员变量不能被序列化

RandomAccessFile类,既可以做输出流,又可以做输入流,因为实现了DateInput接口和DataOutput接口

创建实例的时候需要指定mode类型

r: 以只读方式打开

rw: 读取和写入

rwd:读取和写入,同步文件内容的更新

rws:打开以便读取和写入,同步文件内容和元文件的更新

NIO

NIO和IO有同样的作用和目的,不同的是NIO是面向缓冲区(IO是面向流),基于通道的IO操作,NIO能以更高效的方式进行文件的读写操作

socket进行网络通信

public void client(){
    Socket socket = null;
    OutputStream outputStream = null;

    try {
        //创建socket 指明ip和端口号
        InetAddress inet = InetAddress.getByName("127.0.0.1");
        socket = new Socket(inet,9090);

        //获取输出流
        outputStream = socket.getOutputStream();

        outputStream.write("我是客户端".getBytes());
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if(outputStream != null) {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(socket != null) {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


}
public void server(){
    Socket socket = null;
    InputStream is = null;
    ByteArrayOutputStream bos = null;
    try {
        //创建Socket服务器端,只需要指定端口号
        ServerSocket serverSocket = new ServerSocket(9090);

        //accept()接受来自客户端socket
        socket = serverSocket.accept();
        //获取到输入流
        is = socket.getInputStream();

        //读取输入流的信息
        bos = new ByteArrayOutputStream();
        byte[] buff = new byte[5];
        int len;
        while((len = is.read(buff)) != -1){
            bos.write(buff,0,len);
        }

        System.out.println(bos.toString());
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if(is != null) {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(bos != null) {
            try {
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(socket != null) {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }



}

反射

Reflection(反射)是被视为动态语言的关键。

在加载完类后,堆内存的方法区中就产生了一个class类型的对象,这个对象就包含了类的完整结构,我们可以通过这个对象看到类的结构。这个对象就一面镜子,透过镜子看到类的结构,所以,我们形象的称为:反射。

通过反射,可以调用类的私有结构:如私有构造器、方法、属性。

Class Constructor Method Filed

获取Class实例的方式

Class实例对应着加载到内存中的一个运行时类。

 //方式一:调用运行时类的属性: .class
Class clazz1 = Person.class;
System.out.println(clazz1);

//方式二:通过运行时类的对象,调用getClass()
Person p1 = new Person();
Class clazz2 = p1.getClass();
System.out.println(clazz2);

//方式三:调用Class的静态方法:forName(String classPath)
Class clazz3 = Class.forName("com.atguigu.java.Person");
System.out.println(clazz3);

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

ClassLoader获取properties

//通过ClassLoader类加载器获取properties配置文件里的内容
Properties pro = new Properties();
ClassLoader classLoader = ReflectionTest.class.getClassLoader();
InputStream in = classLoader.getResourceAsStream("jdbc.properties");
pro.load(in);

String user = pro.getProperty("user");
String password = pro.getProperty("password");
System.out.println("user=" + user + ",password=" + password);

创建运行时类的对象

//创建运行时类的对象
Class clazz = Class.forName("com.atguigu.java.Person");
//Object obj = clazz.newInstance();
Person obj = (Person)clazz.newInstance();
System.out.println(obj);

如何操作运行类中的指定的属性

//如何操作运行类中的指定的属性

Class clazz = Person.class;
//创建类的运行时类的对象
Person p = (Person) clazz.newInstance();
//getDeclaredField()获取运行时类中指定的属性
Field name = clazz.getDeclaredField("name");
//保证当前属性是可以访问的
name.setAccessible(true);
//获取、设置指定对象属性的值
name.set(p, "Tom");

System.out.println(name.get(p));//Tom

如何操作运行类中的指定的方法

//如何操作运行类中的指定的方法
        
Class clazz = Person.class;

Person p = (Person)clazz.newInstance();
//getDeclaredMethod():参数1:方法的名称,参数2:方法的形参列表
Method show = clazz.getDeclaredMethod("show", String.class);

show.setAccessible(true);
//invoke():参数1:方法的调用者,参数2:给方法形参赋值的实参
//invoke()方法的返回值即为对应类中方法的返回值
show.invoke(p, "hahahha");
举报

相关推荐

寒假Java学习Day13:

java基础 Day13

寒假:Day13

JVM[day13]

爬虫笔记day13

算法练习-day13

JS基础day13

0 条评论