您的位置:首页 > 编程语言 > Java开发

java基础加强(jdk新特性 javaa设计模式 反射)

2017-11-01 11:38 489 查看

1.Tcp协议发送数据

当使用tcp发送数据的时候 必须的有服务器端,当第一次执行客户端代码会报如下错误

java.net.ConnectException: Connection refused: connect

连接被拒绝

Socket和ServerSocket

建立客户端和服务器端

建立连接后,通过Socket中的IO流进行数据的传输

关闭socket

同样,客户端与服务器端是两个独立的应用程序。

代码实现

[1]客户端代码

1:建立客户端的Socket服务,并明确要连接的服务器。

2:如果连接建立成功,就表明,已经建立了数据传输的通道.就可以在该通道通过IO进行数据的读取和写入.该通道称为Socket流,Socket流中既有读取流,也有写入流.

3:通过Socket对象的方法,可以获取这两个流

4:通过流的对象可以对数据进行传输

5:如果传输数据完毕,关闭资源

public class Client {​

public static void main(String[] args) throws Exception{

//1.创建socket的实例

Socket socket = new Socket(InetAddress.getByName(“192.168.126.26”),9999);

String data = “tcp我来了”;

//2.返回此套接字的输出流。通过输出流向服务器发送数据

socket.getOutputStream().write(data.getBytes());

//3.关闭socket

socket.close();

}

}

[2]服务器代码

1:建立服务器端的socket服务,需要一个端口

2:服务端没有直接流的操作,而是通过accept方法获取客户端对象,在通过获取到的客户端对象的流和客户端进行通信

3:通过客户端的获取流对象的方法,读取数据或者写入数据

4:如果服务完成,需要关闭客户端,然后关闭服务器,但是,一般会关闭客户端,不会关闭服务器,因为服务端是一直提供服务的

public class ServerClient {

public static void main(String[] args) throws Exception{​

//1.创建serversocket对象

ServerSocket ss = new ServerSocket(9999);

//2.侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。 这个对象其实就是发送端的socket对象

Socket socket = ss.accept();

//3.获取客户端发送的数据 要使用输入流

InputStream is = socket.getInputStream();

//4.把数据读取出来

int len =0;

byte buf[] = new byte[1024];

while((len = is.read(buf))!=-1){

String str = new String(buf,0,len);

System.out.println(“服务器:”+str);

}

ss.close();

}​

}

2.客户端发送数据 数据来自键盘录入

public class Client {

public static void main(String[] args) throws Exception{​

//1.创建socket的实例

Socket socket = new Socket(InetAddress.getByName(“192.168.126.26”),9999);

// String data = “tcp我来了”;

Scanner scanner = new Scanner(System.in);

while(sc
4000
anner.hasNext()){

String data = scanner.nextLine();​

//1.1 当用户输入的是886 跳出while循环

if (“886”.equals(data)) {

break;

}

//2.返回此套接字的输出流。通过输出流向服务器发送数据

socket.getOutputStream().write(data.getBytes());

}

scanner.close();

//3.关闭socket

socket.close();

}​

}

3.文件上传核心逻辑

朋友圈,百度网盘 360云盘.邮箱–>上传附件

代码实现:

[1]客户端代码

public class Client {

public static void main(String[] args) throws Exception{​

//1.创建socket的实例

Socket socket = new Socket(InetAddress.getByName(“192.168.126.26”),9999);

//2.先读取abc.txt文件内容

FileInputStream fis = new FileInputStream(“abc.txt”);

int len=0;

byte buf[] = new byte[1024];

while((len=fis.read(buf))!=-1){

//2.返回此套接字的输出流。通过输出流向服务器发送数据

socket.getOutputStream().write(buf, 0, len);

}

fis.close();

//3.关闭socket

socket.close();

}​

}

[2]服务器代码

public class ServerClient {

public static void main(String[] args) throws Exception{

//1.创建serversocket对象

ServerSocket ss = new ServerSocket(9999);

//2.侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。 这个对象其实就是发送端的socket对象

Socket socket = ss.accept();

//3.获取客户端发送的数据 要使用输入流

InputStream is = socket.getInputStream();

FileOutputStream fos =new FileOutputStream(“abcd.txt”);

//4.把数据读取出来 并写到指定文件中

int len =0;

byte buf[] = new byte[1024];

while((len = is.read(buf))!=-1){

fos.write(buf, 0, len);

}

fos.close();

ss.close();

} ​

}

总结 :客户端上传的是什么文件类型 服务器接收的就应该是什么格式.

udp:datagramSocket DatagramPacket

tcp :socket serversockete

4.枚举(1.5)

枚举应用场景,比如我要定义一个星期(1-7)变量 四季(春 夏 秋 冬) 交通灯(红 绿 黄)

枚举就是让某个类型的变量的取值只能为若干个固定的值中的一个,否则,编译器就会报错.枚举可以让编译器在编译时就可以控制源程序中填写非法的值.

我使用一个普通类来模拟枚举的功能.

* 私有的构造方法

* 每个元素分别用一个公有的静态成员变量表示

* 可以有若干公有方法或抽象方法

package com.itheima.enumtest;

//普通类 来模拟枚举功能 模拟星期

//枚举只能是固定的几个实例

public abstract class WeekDay {​

//1.构造方法私有化

private WeekDay(){}

//2.自己创建几个实例 {}代表通过该类的子类完成实例化 就是实现父类为实现的方法

public static WeekDay mon = new WeekDay(){

@Override

public WeekDay nextDay() {

return sun;

}

};

public static WeekDay sun = new WeekDay(){​

@Override

public WeekDay nextDay() {

return mon;

}

};

//3.定义一个方法 nextDay //Perosn

/*public WeekDay nextDay(){

if (this == mon) {

return sun;

}else if (this == sun) {

return mon;

}else {

return null;

}

}*/

//4.为了简化if else 语句 我这样定义

public abstract WeekDay nextDay();

//3.默认打印实例 打印地址 重写toString方法 alt + shift + s

@Override

public String toString() {

if (this == mon) {

return “mon”;

}else if (this == sun) {

return “sun”;

}else{

return “”;

}

}

}

如何定义枚举. class interface enum 实现带抽象方法的枚举

枚举的应用

定义一个weekday的枚举

枚举元素必须位于枚举体中的最开始部分,枚举元素列表后要有分号与其他成员分隔.把枚举中的成员方法或变量等放在枚举元素的前面,编译器会报告错误.

带构造方法的枚举

带方法的枚举

枚举中只有一个成员时,就可以作为一种单利的实现方式

1.枚举相当于一个类.其中也可以定义构造方法,成员变量,普通方法和抽象方法.

2.枚举元素必须位于枚举体中的最开始部分,枚举元素列表后要有分号与其他成员分隔.把枚举中的成员方法

或变量等放在枚举元素的前面,编译器会报告错误.

3.带构造方法的枚举

构造方法必须定义成私有的

如果有多个构造方法,该如何选择哪个构造方法

枚举元素mon和mon()效果一样.都是调用默认的构造方法

4.带方法的枚举

定义枚举TrafficLamp

实现普通的next方法

实现抽象的next方法:每个元素分别是由枚举的子类来生成的实例对象.这些子类采用类似内部类的方式进行定义

public enum Weekday {​

// 这个成员默认是静态:

SUN, MON(2), TUE, WED, THRI, FRI(50), SAT;

// 1.定义构造方法

private Weekday() {

System.out.println(“1111”);

}​

//2.定义一个带参数的构造方法

private Weekday(int day) {

System.out.println(“22222”);

}​

}

带抽象方法的枚举

public enum TrafficLamp {​

RED{

@Override

public TrafficLamp nextLamp() {

return TrafficLamp.GREEN;

}

},GREEN{​

@Override

public TrafficLamp nextLamp() {

return YELLOW;

}

},YELLOW{​

@Override

public TrafficLamp nextLamp() {

return TrafficLamp.RED;

}

};

//定义下一个灯

public abstract TrafficLamp nextLamp();

}

5.单例设计模式

单例设计模式特点: 在内存中只有一个实例存在.

单例设计模式概述

单例模式就是要确保类在内存中只有一个对象,该实例必须自动创建,并且对外提供。

优点

在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能。

缺点

没有抽象层,因此扩展很难。

职责过重,在一定程序上违背了单一职责

5.1饿汉式代码写法

//想保证student对象在内存中只有一个实例

//单例设计模式分类 饿汉式 懒汉式

public class Student {

//1.构造方法私有化

private Student(){}

//2.自己创建一个实例 李四

private static Student s = new Student();

//3.对外提供一个获取实例的方法

public static Student getStudent(){

return s;

}

}

5.2 懒汉式代码写法

public class Teacher {

//1.构造方法私有化

private Teacher(){}

//2.自己先不创建 先声明

private static Teacher t;

//3.提供一个方法获取teacher的实例 t1 t2 t3

public synchronized static Teacher getTeacher(){

if (t == null) {

t = new Teacher();

}

return t;

}



}

6.工厂设计模式

工厂设计模式 可以负责对象的创建 对实例创建进行封装.

工厂模式

工厂模式概述 又叫静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例

优点:客户端不需要在负责对象的创建,从而明确了各个类的职责

缺点:这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者某些对象的创建方式不同,就需要不断的修改工厂类,不利于后期的维护

代码实现过程

1.先定义一个猫和狗的实例

//定义一个猫类

public class Cat extends Anim{

//提供一个吃的方法

public void eat() {

System.out.println(“鱼”);

}

}

//定义一个狗 类

public class Dog extends Anim{​

//提供一个吃的方法

public void eat() {

System.out.println(“肉”);

}

}

2.由于猫和狗都是动物 所以向上抽取了一个动物类

//抽象一个动物类 提供一个吃的方法

public abstract class Anim {



public abstract void eat();

}

3.创建一个工厂 这个工厂负责猫和狗对象的创建

//这个类就负责猫和狗的创建

public class AnimFactory {

//1.不需要提供new对象的方式获取工厂的实例 所以构造方法私有化

private AnimFactory(){};

//2.对外提供一个创建猫和狗实例的方法 参数代表 获取动物的类型

public static Anim getAnim(String type) {

if (“dog”.equals(type)) {

return new Dog();

}else if (“cat”.equals(type)) {

return new Cat();

}else {

return null;

}

} }

7.模板设计模式

模版设计模式概述

模版方法模式就是定义一个算法的骨架,而将具体的算法延迟到子类中来实现

优点

使用模版方法模式,在定义算法骨架的同时,可以很灵活的实现具体的算法,满足用户灵活多变的需求

缺点

如果算法骨架有修改的话,则需要修改抽象类

代码实现过程

1.定义一个计算时间模板

public abstract class GetTime {

//获取一段逻辑执行需要的时间 这个方法相当于是一个计算时间的模板

public long getCodeTime(){

//1.获取当前系统的时间

long startTime = System.currentTimeMillis();

code(); //具体要计算 的业务逻辑让子类去实现

//2.在获取一下系统时间

long endTime = System.currentTimeMillis()-startTime;

return endTime;

}

public abstract void code(); ​

}

2.定义for循环执行1000万次需要的时间

public class GetForTime extends GetTime {

@Override

public void code() {

//1.1 算出 for循环 需要多长时间

for (int i = 0; i < 10000; i++) {

System.out.println(i);

}

}​

}

3.定义拷贝视频的逻辑

public class GetCopyVideoTime extends GetTime {



@Override

public void code() {



//这里写拷贝视频的逻辑



//1.2 算出拷贝一段视频需要多长时间

try {

FileInputStream fis = new FileInputStream(“test.avi”);

FileOutputStream fos = new FileOutputStream(“copy.avi”);

//流对接操作

int len =0;

byte[] buf = new byte[1024];

while((len=fis.read(buf))!=-1){

fos.write(buf, 0, len);

}

fis.close();

fos.close();

} catch (Exception e) {

e.printStackTrace();

}

}​

}

8.适配器设计模式

适配器设计模式概述

将一个类的接口转换成另外一个客户希望的接口。从而使原来不能直接调用的接口变的可以调用。

优点

让本来不适合使用的接口变得适合使用

缺点

一次只能适配一个类,使用有一定的局限性

代码实现过程

1.定义一个接口 接口里面有4个方法



public interface User {



public void add();

public void del();

public void update();

public void query();

}

2.定义一个适配器类 Adapter 默认实现这个接口

public class Adapter implements User {



@Override

public void add() {

}​

@Override

public void del() {​

}​

@Override

public void update() {​

}​

@Override

public void query() {​

}

}

3.定义一个具体的实现类 来继承Adapter类 用到哪个方法就重写哪个方法

public class UserImp2 extends Adapter {

@Override

public void add() {

super.add();

}

}

9. 装饰设计模式

去4s店 买个车 宝马x5 买房 毛坯房 手机(诺基亚) 打电话.

装饰设计模式概述

装饰模式就是使用被装饰类的一个子类的实例,在客户端将这个子类的实例交给装饰类。是继承的替代方案

优点

使用装饰模式,可以提供比继承更灵活的扩展对象的功能,它可以动态的添加对象的功能,并且可以随意的组合这些功能

缺点

正因为可以随意组合,所以就可能出现一些不合理的逻辑

代码实现过程

1.定义一个接口 接口里面有个一个打电话功能

public interface Phone {



public void call();

}

2.向上抽取了一个基本的装饰类 基本的装饰类要保证有通话功能



public abstract class BaseDecorate implements Phone {



//子类在装饰的时候 要保证有基本的通话功能

private Phone p;

public BaseDecorate(Phone p){

this.p = p;

}

@Override

public void call() {



this.p.call();

}​

}

3.在定义具体的装饰类 比如 播放音乐 加彩铃

public class MusicDecorate extends BaseDecorate {



public MusicDecorate(Phone p) {

super(p);

}

@Override

public void call(
bebd
) {

super.call();

System.out.println(“手机可以听音乐了”);

}

}

4.定义一个测试类就可以了

public class TestPhone {



public static void main(String[] args) {

//1.手机可以通话了

Iphone iphone = new Iphone();

iphone.call();

System.out.println(“————-“);

//2.对手机进行装饰 加彩铃 播放音乐 播放视频 不管对手机怎么装饰 都要保证电话的基本功能

RingDecorate ringDecorate = new RingDecorate(iphone);

ringDecorate.call();

System.out.println(“———*—-“);

//3.对iphone继续装饰 加音乐

MusicDecorate musicDecorate = new MusicDecorate(iphone);

musicDecorate.call();​

}​

}

总结设计模式:

1 单例(必须会)

2 工厂设计模式(必须会)

3 模板设计模式(了解)

4.适配器设计模式(必须会)

5.装饰设计模式(了解)



10.Class介绍

黑人 白人 黄人—->人 宝马 奥迪 奔驰 QQ H6(油老虎)—>car String list Map …..>Class

1 java类用于描述一类事物的共性,该类事物有什么属性,至于这个属性的值是什么,则是由这个类的实例对象来确定的,不同的实例对象有不同的属性值.java程序中各个java类,他们是否属于同一类事物呢?这个类的名字就是Class.

java程序中各个java类属于同一类事物,描述这类事物的java类名就是Class(



如何得到各个字节码对应的实例对象

类名.class

对象.getClass

Class.forName(“类名”)

一个Class里面应该有什么呢 构造方法 属性(成员) 方法

获取一个类的Class对象的三种方式:

public class TestClass {

public static void main(String[] args) throws Exception{

String str = “abc”;

//1.获取str 对应的Class对象

Class class1 = str.getClass();

//2.类名.class 只要是在java中你能想到的任何类型 都会有一份字节码对象

Class class2 = String.class;

//3.Class.forName(); 获取Class对象

Class class3 = Class.forName(“java.lang.String”);

System.out.println(class1 == class2);

System.out.println(class2 == class3);

}​

}

第三种和前两种的区别

前两种你必须明确Person类型.

后面是你我这种类型的字符串就行.这种扩展更强.我不需要知道你的类.我只提供字符串,按照配置文件加载就可以了

11.反射

反射概念:反射就是把java中相应的成分(构造方法 成员 方法)映射成相应的类.

反射就是把java类中各种成分映射成相应的java类.

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

11.1获取person类中构造方法

//获取带私有的构造方法

private static void method2() throws Exception{

//1.获取person类的字节码对象(Class) 参数1:要反射类的完整包名 类名

Class class1 = Class.forName(“com.itheima.classtest.Person”);

//2.获取person类中所有的构造方法

Constructor[] declaredConstructors = class1.getDeclaredConstructors();

//3.遍历

for (Constructor constructor : declaredConstructors) {

System.out.println(constructor);

}

}

//alt + shift + M 快速抽取一个方法 获取person类中构造方法 不包含私有的

private static void method1() throws ClassNotFoundException {

//1.获取person类的字节码对象(Class) 参数1:要反射类的完整包名 类名

Class class1 = Class.forName(“com.itheima.classtest.Person”);

//2.获取person类中所有的构造方法

Constructor[] constructors = class1.getConstructors(); //私有获取不到

//3.遍历数组

for (Constructor constructor : constructors) {

System.out.println(constructor);

}

11.2获取person类中单个空参构造方法并且实例化

//获取person类中 public Person(){};

private static void method3() throws Exception{

//1.获取person类的字节码对象(Class) 参数1:要反射类的完整包名 类名

Class class1 = Class.forName(“com.itheima.classtest.Person”);

//2.获取 public Person(){};构造方法 参数:可变参数

Constructor constructor = class1.getConstructor(); //这个类的实例就代表构造方法

//3.通过构造方法获取person的实例

Object object = constructor.newInstance();

System.out.println(object);

}

11.3获取person类中单个带参构造方法并且实例化

//获取person类中单个带参构造方法并且实例化

private static void method4() throws Exception{

//1.获取person类的字节码对象(Class) 参数1:要反射类的完整包名 类名

Class class1 = Class.forName(“com.itheima.classtest.Person”);

//2.获取 public Person(String name,int age,String address);

Constructor constructor = class1.getConstructor(String.class,int.class,String.class);

//3.通过构造方法获取person的实例

Object object = constructor.newInstance(“zhaowei”,20,”沙河”);

System.out.println(object);

}

获取构造方法

getConstructors

getDeclaredConstructors

创建对象

newInstance()

con.newInstance(“zhangsan”, 20);

11.4获取person类中私有的构造方法

//获取person类中私有的构造方法

private static void method5() throws Exception{

//1.获取person类的字节码对象(Class) 参数1:要反射类的完整包名 类名

Class class1 = Class.forName(“com.itheima.classtest.Person”);

//2.获取私有的构造方法 private Person(String name)

Constructor constructor = class1.getDeclaredConstructor(String.class);

//3.暴力反射 其实就是调用一个方法 值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查

constructor.setAccessible(true);

//3.通过构造方法获取person的实例

Object object = constructor.newInstance(“柳岩”);

System.out.println(object);

}

11.5 获取person类中成员(属性并且使用)

// 获取所有的属性 包括私有的

private static void method2() throws Exception{

// 1.获取person类的字节码对象(Class) 参数1:要反射类的完整包名 类名

Class class1 = Class.forName(“com.itheima.classtest.Person”);

// 2.获取person类中所有的属性

Field[] declaredFields = class1.getDeclaredFields();

//3.遍历

for (Field field : declaredFields) {

System.out.println(field);

}

}

// 获取person类中所有的属性

private static void method1() throws Exception {

// 1.获取person类的字节码对象(Class) 参数1:要反射类的完整包名 类名

Class class1 = Class.forName(“com.itheima.classtest.Person”);

// 2.获取person类中所有的属性 (不要考虑私有)

Field[] fields = class1.getFields();

// 3.遍历

for (Field field : fields) {

System.out.println(field);

}

}

11.6获取单个属性并且使用

//获取person类中address属性并且

private static void method3() throws Exception{

// 1.获取person类的字节码对象(Class) 参数1:要反射类的完整包名 类名

Class class1 = Class.forName(“com.itheima.classtest.Person”);

//2.获取address属性并且使用 参数:获取哪个属性

Field field = class1.getField(“address”);

//3.通过构造方法获取person的实例

Constructor constructor = class1.getConstructor();

Object obj = constructor.newInstance();

System.out.println(“—”+obj);//3.给address属性赋值 参数1:代表person的实例

field.set(obj, “上海”);

System.out.println(obj);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐