您的位置:首页 > 理论基础 > 计算机网络

黑马程序员--Java基础学习笔记【单例设计模式、网络编程、反射】

2015-09-25 00:59 1106 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 设计模式分类: 创建模式:是对类的实例化过程的抽象化,又分为类创建模式和对象创建模式 类创建模式:工厂方法模式 对象…:简单工厂(静态工厂方法)模式、抽象工厂模式、单例模式、建造模式… 结构模式:描述如何将类或者对象结合在一起形成更大的结构 适配器模式、缺省模式、合成模式、装饰模式(包装模式)、门面模式… 行为模式:对不同的对象之间划分责任和算法的抽象化 不变模式、策略模式、迭代子模式、命令模式、访问者模式… 单例设计模式(Singleton,一种对象创建模式)
单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。 如何保证类在内存中只有一个对象? 1.私有化类的构造方法 2. 本类的成员位置,创建自己的本类对象 3. 提供公共方法,让外界获取这个本类对象-------------------------------饿汉式--------------------------------/*
* 饿汉式,适合开发
* 在类初始化时,已经自行实例化
*/
class SingletonHungry {
// 已经自行实例化
privatestatic SingletonHungry s = new SingletonHungry();

// 私有的默认构造器
private SingletonHungry() {
}

// 静态工厂方法
publicstatic SingletonHungrygetInstance() {
returns;
}
}---------------------------懒汉式(延迟加载)---------------------------/*
* 懒汉式,适合面试
* 在第一次调用的时候实例化
*/
class SingletonLazy {
// 没有final修饰
privatestatic SingletonLazy s = null;

// 私有的默认构造器
private SingletonLazy() {
}

// // 未考虑线程安全问题
// public static SingletonLazy getInstance() {
// if (s == null) {
// s = new SingletonLazy();
// }
// return s;
// }

// // 静态方法加锁实现线程安全
// public static synchronized SingletonLazy getInstance(){
// if (s == null) {
// s = new SingletonLazy();
// }
// return s;
// }

// 静态工厂方法
// 同步代码块实现线程安全,双重检查实现高效
/*
* 静态方法锁的对象是类对象,每个类都有唯一的一个类对象
* 获取类对象的方式:类名.class
*/
/*
* 静态方法与非静态方法同时声明了 synchronized ,他们之间是非互斥关系的。
* 原因在于,静态方法锁的是类对象,而非静态方法锁的是当前方法所属对象。
*/
publicstatic SingletonLazygetInstance() {
if (s == null) { // 高效
synchronized (SingletonLazy.class) { // 安全
if (s == null) {
s = new SingletonLazy();
}
}
}
returns;
}
} ==============================网络编程===============================InetAddress 类 getByName 获取任意主机的 IP 地址 getHostName 返回字符串形式的主机名 getHostAddress 得到主机字符串形式IP地址端口:计算机与外界通信交流的出口 知名端口:0~1024;动态端口:1024~65535TCP 和 UDP协议TCP:面向连接的保护可靠传输的协议,不定长度的数据UDP:无连接的协议,每个数据包中包含完整的源、目的信息,传输大小有限制 64KB UDP 通信
DatagramPacket 用于发送和接收数据的不同构造方法// 接收数据DatagramPacket(byte[] ibuft, intlength)DatagramPacket(byte[] ibuft, intoffset, int length)// 发送数据(指定对方IP地址和端口)DatagramPacket(byte[] ibuf, intilength, InetAddress iaddr, int port)DatagramPacket(byte[] ibuf, intoffset, int ilength, InetAddress iaddr, int port) DatagramPacket 对象的常用方法InetAddress getAddress() // 返回远程主机的IP地址byte[] getData() // 返回字节数组类型的数据int getLength() // 返回数据的字节数int getPort() // 返回远程主机的端口号SocketAddress getSocketAddress() // 返回远程主机的SocketAddressint getOffset() // 返回数据的偏移量 DatagramSocket 对象的创建及常用方法 DatagramSocket() DatagramSocket(int port) DatagramSocket(int port,InetAddress iaddr) InetAddress getLocalAddress() // 获取套接字绑定本机IP地址 int getLocalPort() // 返回套接字绑定本机端口号 SocketAddressgetLocalSocketAddress() // 返回包含IP地址和端口号的sa void receive(DatagramPacket dp)// 接收数据包 void send(DatagramPacket dp) // 发送数据包 数据报套接字,接收端和发送端程序的编写步骤
接收端:(明确端口:指定端口或随机端口)调用DatagramSocket(int port)创建一个数据报套接字,并绑定到指定端口

调用DatagramPacket(byte[] buf,int length),建立一个字节数组以接收UDP包

调用DatagramSocket类的receive()方法,接收UDP包

最后关闭数据报套接字

发送端:(不需指定端口)调用DatagramSocket()创建一个数据报套接字

调用DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port),建立要发送的UDP包

调用DatagramSocket类的send()方法,发送UDP包

最后关闭数据报套接字

TCP 通信
Socket 的构造方法及常用方法Socket(String host, int port)Socket(InetAddress host, int port)InputStream getInputStream()OutputStream getOutputStream()InetAddress getInetAddress() // 返回套接字连接的地址int getPort() // 返回套接字连接到的远程端口close() ServerSocket 的构造方法及常用方法ServerSocket(int port)ServerSocket(int port, int queuelength)// 指定本地端口号,连接请求队列的长度(最大连接数目),本地网络地址ServerSocket(int port, int queuelength, InetAddressbindaddress)accept() // 侦听并接受套接字的连接close() C/S通信的编写步骤
服务器端的编写流程:指定本地端口号,创建ServerSocket对象,监听指定端口的 Socket 连接

使用 ss 对象的accept()方法,接收的客户端连接请求,返回Socket 对象

获取Socket对象的输入/输出流

接收数据,处理数据,回传数据

关闭流和 Socket,关闭 ServerSocket

客户端的编写流程1. 指定要连接的 IP 地址和端口号,创建Socket对象
2. 获取 socket 对象的输入/输出流
3. 读写字节流数据
4. 关闭流,关闭 Socket
客户端与服务端通信模型如下:


1. 服务端创建ServerSocket2. 通过调用ServerSocket的accept方法监听客户端的连接3. 客户端创建Socket并指定服务端的地址以及端口来建立与服务端的连接4. 当服务端accept发现客户端连接后,获取对应该客户端的Socket5. 双方通过Socket分别获取对应的输入与输出流进行数据通讯6. 通讯结束后关闭连接。 反射 reflection
Java中类的反射是一种自我管理机制,通过反射可实现:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和成员方法;在运行时调用任意一个对象的方法。 类的加载过程:加载:将.class文件读入内存,并为之创建一个 Class 对象连接:验证内部结构准备静态成员分配内存默认初始化解析二进制数据中的符号引用 --> 直接引用初始化:类初始化时机:创建实例,访问静态变量,调用静态方法,反射强行加载,初始化子类,运行主类 三种方式获取Class文件对象
// 使用父类方法 getClass 获取
Classclass1= p.getClass();
System.out.println(class1);

// 使用类的静态属性 class
Classclass2= Person.class;
System.out.println(class2);

// 使用Class类的静态方法 forName
// 全类名
Classclass3= Class.forName("cn.itcast.Person");
System.out.println(class3); 通过反射获取构造方法并使用
// 获取class文件中的公有的构造方法
Constructor<?>[]constructors= class3.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}

// 获取指定构造方法,空参数
Constructor<?>constructor= class3.getConstructor();

// 运行获取到的构造方法
Objectobject= constructor.newInstance();
System.out.println(object);

System.out.println("--------------------------");
// 获取带参数构造方法
// 传递参数列表,要传递这个数据类型的class对象
Constructorconstructor2= class3.getConstructor(String.class, int.class);

Objectobject2= constructor2.newInstance("zs", 20);
System.out.println(object2);

System.out.println("--------------------------");
// 获取所有的构造方法
Constructor<?>[]constructors2= class3.getDeclaredConstructors();
for (Constructor<?> constructor3 : constructors2) {
System.out.println(constructor3);
}

// 获取私有构造方法并运行
Constructorconstructor3= class3.getDeclaredConstructor(String.class);

// //调用Constructor父类方法 setAccessible(true)
// constructor3.setAccessible(true);// 暴力访问,不建议使用

// constructor3.newInstance("ls");// java.lang.IllegalAccessException
// System.out.println(constructor3);

System.out.println("==========================");

// 保证空参数的构造方法存在,并且具有可访问权限
Classclazz= Class.forName("cn.itcast.Person");
// 不获取构造方法,直接调用具有可访问权限的空参数的构造方法
Objectobject3= clazz.newInstance();
System.out.println(object3); 通过反射获取成员变量并使用
// 获取所有公共成员变量
Field[]fields= clazz.getFields();
for (Field field : fields) {
System.out.println(field);
}

// 获取指定成员变量
// Fieldfields2 = clazz.getField("age");
// System.out.println(fields2);

// 修改获取到的成员变量值,必须有这个类的支持
// Objectobj = clazz.newInstance();
// fields2.set(obj,22);

// 获取所有成员变量
clazz.getDeclaredFields();
// 获取指定的成员变量
clazz.getDeclaredField("age"); 通过反射获取成员方法并使用
// 获取所有公共成员方法和继承的
Method[]methods= clazz.getMethods();
for (Method method : methods) {
System.out.println(method);
}

// 获取指定的成员方法 (字符串方法名,Class类型的参数列表)
Methodmethod= clazz.getMethod("toString");
System.out.println(method);
// 运行获取到的方法,传递对象和实际参数
Objectobj= clazz.newInstance();
method.invoke(obj);

Methodmethod2= clazz.getMethod("setName",String.class);
System.out.println(method2);
method2.invoke(obj, "ww");

// 获取所有成员方法,不包括继承的
clazz.getDeclaredMethods();
// 获取指定的成员方法
// clazz.getDeclaredMethod(name,parameterTypes); 已知ArrayList<Integer>的一个对象,如何实现往集合中添加一个字符串数据?
package cn.itcast;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

/*
* 考查对反射原理的理解
* 反射将泛型进行擦除
* 反射绕过编译器检查,将不同的数据类型存储到带泛型的集合
*/
publicclassReflectTest {

publicstaticvoid main(String[] args) throws NoSuchMethodException,SecurityException, IllegalAccessException,
IllegalArgumentException,InvocationTargetException {
ArrayList<Integer>list= newArrayList<>();
list.add(0);
list.add(1);
list.add(2);
list.add(3);

// 反射获取ArrayList.class 文件中的add() 方法
Classclazz= list.getClass();
Methodmethod= clazz.getMethod("add", Object.class);
method.invoke(list, "itcast");

System.out.println(list);
}

}

本文出自 “听你流浪” 博客,请务必保留此出处http://zhanglianxin.blog.51cto.com/8312202/1698036
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: