回顾Java知识点,面试题汇总Day18(持续更新)

一、反射

通过一个实例化对象映射到类,在程序运行期间就可以获取类的信息,进行相关操作。

1.1 Class类

Class类是反射的基础

用一个对象来表示某个类的信息,通过Class类来创建

Class是专门用来描述其他类的类,每一个Class对象都是对某个类的具体描述

  • 调用forName方法
  • 通过目标类的类字面量获取
  • 通过目标类的实例化对象获取
java 复制代码
public class Test7 {
    public static void main(String[] args) throws Exception{
        /**
         * 反射的三种方法
         */
        //forName()
       Class clazz1 =  Class.forName("User");
        System.out.println(clazz1);
        //类字面量
        Class clazz2 = User.class;
        System.out.println(clazz2);
        //实例化对象
        User user = new User(1,"dyz");
        Class clazz3 = user.getClass();
        System.out.println(clazz3);
        System.out.println(clazz1 == clazz2);
        System.out.println(clazz2 == clazz3);
    }
    }

上述3种方式获取的Class对象都是同一个,因为每个类在内存中只有一份,对应的对象(描述内部结构的对象)也只有一份。(类就只有一个)

1.2 反射的常见方法

|----------------------------------------------------------|------------------------------------|
| 方法 | 描述 |
| public boolean isInterface() | 判断类是否为接口 |
| public boolean isArray() | 判断类是否为数组 |
| public boolean isAnnotation() | 判断类是否为注解 |
| public String getName() | 获取类名 |
| public ClassLoader getClassLoader() | 获取类加载器 |
| public Class getSuperclass() | 获取类的父类 |
| pubic Package getPackage() | 获取类所在的包 |
| public String getPackageName() | 获取类所在的包名 |
| public Class\[\] getInterfaces() | 获取类的接口 |
| public int getModifiers() | 获取类的访问权限修饰符 |
| public Field\[\] getFileds() | 获取类的全部公有成员变量,包括继承父类和自定义的 |
| public Field\[\] getDeclareFields() | 获取类的自定义成员变量 |
| public Field\[\] getField(String name) | 通过名称获取类的公有成员变量(public),包括继承父类和自定义的 |
| public Field\[\] getDeclareField(String name) | 通过名称获取类的自定义成员变量(自己定义的) |
| public Method\[\] getMethods() | 获取类的全部公有方法(public),包括继承父类和自定义的 |
| public Method\[\] getDeclaredMethods() | 获取类的自定义方法(自己定义的方法) |
| public Method getMethod(String name,Class...pars) | 通过名称和参数信息获取类的公有方法,包括继承父类和自定义的 |
| public Method getDeclareMethod(String name,Class.. pars) | 通过名称和参数信息获取类的自定义方法 |
| public Constructor\[\] getConstructors() | 获取类的全部公有构造器 |
| public Constructor\[\] getDeclareConstructors() | 获取类的全部构造器 |
| public Constructor getConstructor(Class... pars) | 通过参数信息获取类的公有构造器 |
| public Constructor getDeclareConstructor(Class... pars) | 通过参数信息获取类的构造器 |

了解:

java 复制代码
package com.xlh;

import java.io.*;

public class Test {
    public static void main(String[] args) throws Exception{        
        Class clazz1 = Class.forName("com.xlh.User");
        System.out.println(clazz1);  //class com.xlh.User
        System.out.println(clazz1.isInterface()); //判断是否为接口  false
        System.out.println(clazz1.isArray()); //判断是否为数组  false
        System.out.println(clazz1.isAnnotation()); //判断是否为注解  false
        System.out.println(clazz1.getName());//获取类名  com.xlh.User
        System.out.println(clazz1.getClassLoader());//获取类加载器   jdk.internal.loader.ClassLoaders$AppClassLoader@1f89ab83
        System.out.println(clazz1.getSuperclass());//获取父类  Object
        System.out.println(clazz1.getPackage());//获取类所在的包 package com.xlh
        System.out.println(clazz1.getPackageName());//获取类所在的包名  com.xlh
        Class[] interfaces = clazz1.getInterfaces();  //获取类的接口
        for (Class aclazz : interfaces){
            System.out.println(aclazz);  //interface java.io.Serializable
        }
        int modifiers = clazz1.getModifiers();
        System.out.println(modifiers); //获取类的访问权限修饰符   返回1,因为只有public
    }
}

实际开发中常用:

java 复制代码
 Class clazz = Class.forName("com.xlh.User");
        Field[] fields = clazz.getFields();
        for (Field field: fields){
            System.out.println(field); //类的所有公有成员变量,包括父类和自定义的    public int com.xlh.People.id    public java.lang.String com.xlh.People.name
        }
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declareField : declaredFields){
            System.out.println(declareField); //获取自己的所有属性 不管公有还是私有   private int com.xlh.User.id     private java.lang.String com.xlh.User.name
        }

        System.out.println(clazz.getField("id"));//拿到的是People中的id,User中的id和name是private 拿不到
        System.out.println(clazz.getDeclaredField("id"));//拿去自己的属性  不管公有还是私有  获取的是User中的id
        

二、反射的应用

java 复制代码
package test;

public class Student {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public void show(){
        System.out.println("学生信息");
        System.out.println("ID:" + this.id);
        System.out.println("姓名:" + this.name);
    }

    public int test(int num,int num1){
        return num+num1;
    }
}

2.1 反射调用方法

java 复制代码
package test;

import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) throws Exception{
        Student student = new Student();
        student.setId(1);
        student.setName("dyz");
        //常规调用
        student.show();
        //反射调用:操作方法
        Class clazz = Student.class;
        Method show = clazz.getMethod("show", null);
        show.invoke(student,null);

        Method method = clazz.getMethod("test", int.class,int.class);
        Object invoke = method.invoke(student, 1, 2);
        System.out.println(invoke);
    }
}

2.2 反射访问成员变量

java 复制代码
package test;

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

public class Test {
    public static void main(String[] args) throws Exception {
        Class clazz = Student.class;
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields){
            int modifiers = declaredField.getModifiers();
            Class<?> type = declaredField.getType();
            String name = declaredField.getName();
            System.out.println("成员变量" + name + "的数据类型是:" + type + "访问权限是:" + getModifiers(modifiers));
        }
    }
    public static String getModifiers(int modifiers){
        String result = null;
        switch (modifiers){
            case 0:
                result="";
                break;
            case 1:
                 result ="public";
                break;
            case 2:
                result= "private";
                break;
            case 3:
                result= "protected";
                break;
        }
        return result;
    }
    }

2.3 反射调用构造器

私有方法不能访问,通过访问公有方法反射私有属性。

java 复制代码
package test;

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

public class Test {
    public static void main(String[] args) throws Exception {
        Class clazz = Student.class;
        Constructor<Student> constructor = clazz.getConstructor(); //获取无参构造器,不传参数
        Student student = constructor.newInstance(); //创建实例
        Method setId = clazz.getMethod("setId", int.class);
        setId.invoke(student,1);
        Method getId = clazz.getMethod("getId", null);
        System.out.println(getId.invoke(student));
    }
}

三、网络编程

如何使用Java开发基于web的应用

3.1 IP和端口

IP:互联网中每台终端设备都有一个唯一标识,网络中的请求可以根据这个标识找到具体的终端,这个唯一标识就是IP。

端口:8080、3306

3.2 TCP协议

TCP协议面向连接的运输层协议,比较复杂,安全但效率低,使用TCP协议前必须先建立连接,才能传输数据,数据传输完毕后释放连接。

3.2.1 ServerScoket

|---------------------------------------------------------------|------------------------|
| 方法 | 解释 |
| public ServerSocket(int port) | 根据端口创建ServerSocket对象 |
| public ServerSocket(int port,int backlog,InetAddress address) | 根据端口、backlog 、IP地址创建对象 |
| public Socket accpept() | 等待客户端请求,返回Socket对象 |
| public void close() | 关闭ServerSocket |

3.2.2 Socket

|------------------------------------------|-----------------------|
| 方法 | 解释 |
| public Socket(String host,int port) | 根据主机、端口创建要连接的Socket对象 |
| public Socket(InetAddress host,int port) | 根据IP、端口创建要连接的Socket对象 |
| public InputStream getInputStream() | 获取Socket输入流 |
| public synchronized void close() | 关闭Socket |

java 复制代码
package test;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) throws Exception{
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        DataInputStream dataInputStream = null;
        DataOutputStream dataOutputStream = null;
        serverSocket = new ServerSocket(8080);
        System.out.println("服务器端已启动,等待接收");
        Socket accept = serverSocket.accept();
//        System.out.println(accept);
        inputStream = accept.getInputStream();
        dataInputStream = new DataInputStream(inputStream);
        String request = dataInputStream.readUTF();
        System.out.println("接收到了客户端请求" + request);
        String response = "Hello Word";
        outputStream = accept.getOutputStream();
        dataOutputStream = new DataOutputStream(outputStream);
        dataOutputStream.writeUTF(response);
        System.out.println("给客户端做出回应" + response);

        //关闭
        accept.close();
        serverSocket.close();
        inputStream.close();;
        outputStream.close();
        dataOutputStream.close();
        dataInputStream.close();
    }
}
java 复制代码
package test;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class Client {
    public static void main(String[] args) throws Exception{
        Socket socket = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        DataOutputStream dataOutputStream = null;
        DataInputStream dataInputStream = null;
        socket = new Socket("127.0.0.1",8080);
        System.out.println("客户端接收");
        System.out.println(socket);
        //给服务器发消息
        String msg = "你好呀!";
        System.out.println("客户端说:" + msg);
        outputStream = socket.getOutputStream();
        dataOutputStream = new DataOutputStream(outputStream);
        dataOutputStream.writeUTF(msg);

        //接收服务器发来的消息
        inputStream = socket.getInputStream();
        dataInputStream = new DataInputStream(inputStream);
        String s = dataInputStream.readUTF();
        System.out.println("服务器响应" + s);


        //关闭
        socket.close();
        inputStream.close();
        outputStream.close();
        dataOutputStream.close();
        dataInputStream.close();


    }
}

3.3 UDP协议

TCP优点是稳定安全,缺点是效率低,UDP恰好相反,优点是效率高,缺点是不安全。

3.3.1 DatagramSocket

|-----------------------------------------------|------------------------|
| 方法 | 描述 |
| public DatagramSocket(int port) | 根据端口创建DatagramSocket对象 |
| public void send(DatagramPacket p) | 发送数据包 |
| public synchronized receive(DatagramPacket p) | 接收数据包 |

3.3.2 DatagramPacket

|-----------------------------------------------------------------------------|----------------------------------------|
| 方法 | 描述 |
| public DatagramPacket(byte buf\[\],int length,InetAddress address,int port) | 根据发送的数据、数据长度、IP地址、端口创建DatagramPacket对象 |
| public synchronized byte\[\] getData() | 获取接收的数据 |
| public synchronized int getLength() | 获取数据长度 |
| public synchronized int getPort() | 获取发送数据的Socket端口 |

java 复制代码
package test;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketAddress;

public class TerminalA {
    public static void main(String[] args) throws  Exception{
        byte[] buff = new byte[1024];
        DatagramPacket datagramPacket = new DatagramPacket(buff, buff.length);
        DatagramSocket datagramSocket = new DatagramSocket(8081);
        datagramSocket.receive(datagramPacket);
        String message = new String(datagramPacket.getData(),0,datagramPacket.getLength());
        System.out.println("我是TerminalA终端,接收到了" + datagramSocket + "端口" + "传来的数据:" + message);

        //回应B
        String reply = "我是TerminalA,已经接收到了你传来的数据";
        SocketAddress socketAddress = datagramPacket.getSocketAddress();
        DatagramPacket datagramPacket1 = new DatagramPacket(reply.getBytes(),reply.getBytes().length,socketAddress);
        datagramSocket.send(datagramPacket1);

    }
}
java 复制代码
package test;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;

public class TerminalB {
    public static void main(String[] args) throws Exception{
        String message = "你好,我是TerminalB。";
        InetAddress inetAddress = InetAddress.getByName("localhost");
        DatagramPacket datagramPacket = new DatagramPacket(message.getBytes(),message.getBytes().length,inetAddress,8081);
        DatagramSocket datagramSocket = new DatagramSocket(8080);
        datagramSocket.send(datagramPacket);

        //接受到A的回应
        byte[] bytes = new byte[1024];
        DatagramPacket datagramPacket1 = new DatagramPacket(bytes, bytes.length);
       datagramSocket.receive(datagramPacket1);
       String reply = new String(datagramPacket1.getData(),0,datagramPacket1.getLength());
        System.out.println("我是TerminalB,接收到了" + datagramPacket1.getPort() + "发送来的数据" + reply);


    }
}

3.4 多线程的网络编程

java 复制代码
package test;

import java.net.ServerSocket;
import java.net.Socket;

public class ServerThread {
    public static void main(String[] args) throws Exception{
        ServerSocket serverSocket = new ServerSocket(8080);
        System.out.println("服务器启动..");
        while(true){
            Socket socket = serverSocket.accept();
            new Thread(new ServerRunnable(socket)).start();
        }

    }
}
java 复制代码
package test;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

public class ServerRunnable implements Runnable{
    private Socket socket;

    public ServerRunnable(Socket socket) {
        this.socket = socket;
    }


    //input 读入
    @Override
    public void run() {
        InputStream inputStream = null;
        DataInputStream dataInputStream = null;
        try {
            inputStream = this.socket.getInputStream();
            dataInputStream = new DataInputStream(inputStream);
            String message = dataInputStream.readUTF();
            System.out.println(message);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                dataInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
java 复制代码
package test;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class ClientRunnable implements Runnable{
  private  int num;

  public ClientRunnable(int num){
      this.num = num;
  }

    @Override
    public void run() {
        Socket socket = null;
        OutputStream outputStream = null;
        DataOutputStream dataOutputStream = null;
        try {
            socket = new Socket("localhost",8080);
            String message = "我是客户端" +this.num;
            outputStream = socket.getOutputStream();
            dataOutputStream = new DataOutputStream(outputStream);
            dataOutputStream.writeUTF(message);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                dataOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

    }
}
java 复制代码
package test;

public class ClientThread {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(new ClientRunnable(i)).start();

        }
    }
}
相关推荐
小yu学编程1 小时前
IDEA 2025版本中如何设置包层级结构
java·ide·intellij-idea·层级结构
YXWik61 小时前
CodeGraph安装及在idea的claude code插件中使用
java·ide·intellij-idea
zzipeng1 小时前
Linux 并发与竞争
java·linux·运维
27669582921 小时前
京东随机变速滑块拼图验证码识别(京东E卡)
java·服务器·前端·python·京东滑块·京东变速滑块·京东e卡绑卡
未若君雅裁2 小时前
ArrayList 源码全解析:动态扩容、数组互转与底层原理
java
Java程序员-小白2 小时前
Spring Boot整合Sa-Token框架(入门篇)
java·spring boot·后端·sa-token
NE_STOP2 小时前
Docker--初识Dockerfile
java
码哥字节3 小时前
升到 Spring Boot 4.1,虚拟线程开了,HikariCP 连接池却崩了
java·springboot·claude code