一、反射
通过一个实例化对象映射到类,在程序运行期间就可以获取类的信息,进行相关操作。
1.1 Class类
Class类是反射的基础
用一个对象来表示某个类的信息,通过Class类来创建
Class是专门用来描述其他类的类,每一个Class对象都是对某个类的具体描述
- 调用forName方法
- 通过目标类的类字面量获取
- 通过目标类的实例化对象获取
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) | 通过参数信息获取类的构造器 |
了解:
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 } }实际开发中常用:
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二、反射的应用
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 反射调用方法
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 反射访问成员变量
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 反射调用构造器
私有方法不能访问,通过访问公有方法反射私有属性。
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 |
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(); } }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端口 |
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); } }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 多线程的网络编程
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(); } } }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(); } } } }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(); } } } }package test; public class ClientThread { public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread(new ClientRunnable(i)).start(); } } }