Java基础---网络编程、反射

来源:互联网 发布:手机拍照扫描软件 编辑:程序博客网 时间:2024/06/16 01:44
-----------android培训、java培训、java学习型技术博客、期待与您交流!------------

一、网络编程

1、网络编程三要素

(1)IP地址

(2)端口

(3)协议

2、IP地址

网络中计算机的唯一标识。

IP地址的组成:网络号段+主机号段

A类:第一号段为网络号段+后三段的主机号段

一个网络号:256*256*256 = 16777216

B类:前二号段为网络号段+后二段的主机号段

一个网络号:256*256 = 65536

C类:前三号段为网络号段+后一段的主机号段

一个网络号:256

3、IP地址的分类:

A类 1.0.0.1---127.255.255.254

(1)10.X.X.X是私有地址(私有地址就是在互联网上不使用,而被用在局域网络中的地址)

(2)127.X.X.X是保留地址,用做循环测试用的。

B类 128.0.0.1---191.255.255.254 172.16.0.0---172.31.255.255是私有地址。169.254.X.X是保留地址。

C类 192.0.0.1---223.255.255.254 192.168.X.X是私有地址

D类 224.0.0.1---239.255.255.254

E类 240.0.0.1---247.255.255.254

3、两个DOS命令:

ipconfig 查看本机ip地址

ping 后面跟ip地址。测试本机与指定的ip地址间的通信是否有问题

特殊的IP地址:

127.0.0.1 回环地址(表示本机)

x.x.x.255 广播地址

x.x.x.0 网络地址

4、端口号

正在运行的程序的标识。

有效端口:0~65535,其中0~1024系统使用或保留端口。

二、协议

1、通信的规则

(1) UDP:

把数据打包

数据有限制

不建立连接

速度快

不可靠

面向无连接,数据不安全,速度快。不区分客户端与服务端。

(2)TCP:

建立连接通道

数据无限制

速度慢

可靠
  

2、面向连接(三次握手),数据安全,速度略低。分为客户端和服务端。

三次握手: 客户端先向服务端发起请求, 服务端响应请求, 传输数据

3、Socket

通信的两端都有Socket。

网络通信其实就是Socket间的通信。

数据在两个Socket间通过IO流传输。

Socket在应用程序中创建,通过一种绑定机制与驱动程序建立关系,告诉自己所对应的IP和port。

4、udp

(1)UDP协议接收数据

A:创建接收端Socket对象

B:创建一个数据包(接收容器)

C:调用Socket对象的接收方法接收数据

D:解析数据包,并显示在控制台

E:释放资源

(2)UDP协议发送数据

A:创建发送端Socket对象

B:创建数据,并把数据打包

C:调用Socket对象的发送方法发送数据包

D:释放资源

5、案例

[java] view plaincopyimport java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class ReceiveDemo { public static void main(String[] args) throws IOException { // 创建接收端Socket对象 // DatagramSocket(int port) DatagramSocket ds = new DatagramSocket(10086); // 创建一个数据包(接收容器) // DatagramPacket(byte[] buf, int length) byte[] bys = new byte[1024]; int length = bys.length; DatagramPacket dp = new DatagramPacket(bys, length); // 调用Socket对象的接收方法接收数据 // public void receive(DatagramPacket p) ds.receive(dp); // 阻塞式 // 解析数据包,并显示在控制台 // 获取对方的ip // public InetAddress getAddress() InetAddress address = dp.getAddress(); String ip = address.getHostAddress(); // public byte[] getData():获取数据缓冲区 // public int getLength():获取数据的实际长度 byte[] bys2 = dp.getData(); int len = dp.getLength(); String s = new String(bys2, 0, len); System.out.println(ip + "传递的数据是:" + s); // 释放资源 ds.close(); } } import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class SendDemo { public static void main(String[] args) throws IOException { // 创建发送端Socket对象 // DatagramSocket() DatagramSocket ds = new DatagramSocket(); // 创建数据,并把数据打包 // DatagramPacket(byte[] buf, int length, InetAddress address, int port) // 创建数据 byte[] bys = "hello,udp,我来了".getBytes(); // 长度 int length = bys.length; // IP地址对象 InetAddress address = InetAddress.getByName("192.168.12.92"); // 端口 int port = 10086; DatagramPacket dp = new DatagramPacket(bys, length, address, port); // 调用Socket对象的发送方法发送数据包 // public void send(DatagramPacket p) ds.send(dp); // 释放资源 ds.close(); } } 6、UDP多线程[java] view plaincopyimport java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class ReceiveThread implements Runnable { private DatagramSocket ds; public ReceiveThread(DatagramSocket ds) { this.ds = ds; } public void run() { try { while (true) { // 创建一个包裹 byte[] bys = new byte[1024]; DatagramPacket dp = new DatagramPacket(bys, bys.length); // 接收数据 ds.receive(dp); // 解析数据 String ip = dp.getAddress().getHostAddress(); String s = new String(dp.getData(), 0, dp.getLength()); System.out.println("from " + ip + " data is : " + s); } } catch (IOException e) { e.printStackTrace(); } } } import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class SendThread implements Runnable { private DatagramSocket ds; public SendThread(DatagramSocket ds) { this.ds = ds; } public void run() { try { // 封装键盘录入数据 BufferedReader br = new BufferedReader(new InputStreamReader( System.in)); String line = null; while ((line = br.readLine()) != null) { if ("886".equals(line)) { break; } // 创建数据并打包 byte[] bys = line.getBytes(); // DatagramPacket dp = new DatagramPacket(bys, bys.length, // InetAddress.getByName("192.168.1.106"), 13456); DatagramPacket dp = new DatagramPacket(bys, bys.length, InetAddress.getByName("192.168.1.106"), 13456); // 发送数据 ds.send(dp); } // 释放资源 ds.close(); } catch (IOException e) { e.printStackTrace(); } } } 
三、反射

1、反射

(1)Class

.class文件加载到内存中就是一个Class对象

获取Class对象的方式有3种:

Scanner sc = newScanner("xxx.txt");

Class.forName(sc.nextLine());

类名.class

对象.getClass()

(2)案例

[java] view plaincopyimport cn.bean.Person; public class Demo1_Reflect { public static void main(String[] args) throws ClassNotFoundException { Class<?> clazz1 = Class.forName("cn.bean.Person"); Class<?> clazz2 = Person.class; Person p = new Person(); Class<?> clazz3 = p.getClass(); System.out.println(clazz1 == clazz2); System.out.println(clazz2 == clazz3); } } 
2、Constructor

(1)Class类的newInstance()方法是使用该类无参的构造函数创建对象, 如果一个类没有无参的构造函数, 就不能这样创建了

可以调用Class类的getConstructor(String.class,int.class)方法获取一个指定的构造函数

然后再调用Constructor类的newInstance("张三",20)方法创建对象

反射中构造方法的获取方式

(2)步骤:

A:获取到指定类所对应的字节码文件对象 .class对象

B:通过字节码文件对象,获取文件中的构造方法

C:通过构造方法,创建对象

(3)方法:

A:获取一个构造方法

public Constructor getConstructor(Class... parameterTypes) 获取指定的public修饰的构造方法

public Constructor getDeclaredConstructor(Class... parameterTypes) 获取指定的构造方法,包含私有修饰的

B:获取多个构造方法

public Constructor[] getConstructors() 获取所有public修饰的构造方法

public Constructor[] getDeclaredConstructors() 获取所有的构造方法,包含私有的

[java] view plaincopyimport java.lang.reflect.Constructor; import cn.bean.Person; public class Demo3_Constructor { public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName("cn.itcast.bean.Person"); /*Person p = (Person) clazz.newInstance(); System.out.println(p);*/ Constructor con = clazz.getConstructor(String.class,int.class);//获取有参的构造函数 Person p = (Person) con.newInstance("小李",23); //创建对象 System.out.println(p); //打印对象 } } 
3、Field

(1)Class.getField(String)方法可以获取类中的指定字段(可见的), 如果是私有的可以用getDeclaedField("name")方法获取

通过set(obj, "李四")方法可以设置指定对象上该字段的值, 如果是私有的需要先调用setAccessible(true)设置访问权限

用获取的指定的字段调用get(obj)可以获取指定对象中该字段的值

(2)通过反射, 获取到成员变量

方法:

Class

获取一个成员变量

public Field getDeclaredField(String name)

public Field getField(String name)

获取多个成员变量

public Field[] getDeclaredFields()

public Field[] getFields()

[java] view plaincopyimport java.lang.reflect.Constructor; import java.lang.reflect.Field; import cn.bean.Person; public class Demo4_Field { public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName("cn.itcast.bean.Person"); Constructor con = clazz.getConstructor(String.class,int.class);//获取有参的构造函数 Person p = (Person) con.newInstance("小李",23); //创建对象 /*Field f = clazz.getField("name"); System.out.println(f);*/ Field f = clazz.getDeclaredField("name"); //暴力反射 f.setAccessible(true); //去除权限 f.set(p, "小王"); System.out.println(p); } 
4、Method

(1)Class.getMethod(String, Class...) 和 Class.getDeclaredMethod(String, Class...)方法可以获取类中的指定方法

调用invoke(Object,Object...)可以调用该方法

Class.getMethod("eat")invoke(obj) Class.getMethod("eat",int.class) invoke(obj,10)

(2)通过反射机制,获取方法

方法

Class:

获取一个方法:

public Method getMethod(String name, Class<?>... parameterTypes)

public Method getDeclaredMethod(String name, Class<?>... parameterTypes)

获取多个方法:

public Method[] getMethods() 获取本类与父类中所有的public修饰的方法

public Method[] getDeclaredMethods() 只获取本类中所有的方法,包含私有的

[java] view plaincopyimport java.lang.reflect.Constructor; import java.lang.reflect.Method; import cn.bean.Person; public class Demo5_Method { public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName("cn.itcast.bean.Person"); Constructor con = clazz.getConstructor(String.class,int.class);//获取有参的构造函数 Person p = (Person) con.newInstance("张三",23); //创建对象 Method m = clazz.getMethod("eat"); m.invoke(p); Method m2 = clazz.getMethod("eat", int.class); m2.invoke(p, 10); } } 
四、java5的静态导入

1、Importjava.lang.Math.*

可变参数与OverLoad

[java] view plaincopypublic class Demo{ public static void main(String[] args){ System.out.println(add(2,3)); System.out.println(add(2,3,5)); } public static int add(int x,int…args) { int sum=x; for(int arg:args){ sun+=arg; } return sum; } } 
2、增强for循环

普遍用数组与集合中的遍历元素

[java] view plaincopypublic class Demo { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); for (Object obj:list){ System.out.println(obj); } } } 
3、枚举

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

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

(2)带构造方法的枚举

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

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

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

(3)带方法的枚举

定义枚举TrfficLamp

实现普通的next方法

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

增加上表示时间的构造方法。

(4)枚举只有一个成员时,就可以作为一种单例的实现方式。

[java] view plaincopypublic class Fu7 { public static void main(String[] args) { Weekday1 weekday1=Weekday1.fir; System.out.println(weekday1); System.out.println(weekday1.ordinal()); System.out.println(weekday1.name()); System.out.println(weekday1.valueOf("sun")); System.out.println(weekday1.values().length); } public enum Weekday1{ sun(1),mon,tue(1),wed,trt,fir,sat; private Weekday1(){System.out.println("first");} private Weekday1(int i){System.out.println("second");} } //实现带有抽象方法的枚举 public enum TrafficLamp{ RED(30){ public TrafficLamp nextLamp(){ return GREEN; } } GREEN(45){ public TrafficLamp nextLamp(){ return YELLOW; } } YELLOW(5){ public TrafficLamp nextLamp(){ return RED; } }; public abstract TrafficLamp nextLamp{ private int time; private TrafficLamp(int time){this.time=time;} } } 
4、反射的应用例子

(1)创建一个集合对象,泛型为String类型,需要向这个集合中添加Integer对象

泛型在编译时存在,运行时会被擦除

泛型反射

[java] view plaincopyimport java.lang.reflect.Method; import java.util.ArrayList; public class Test3 { public static void main(String[] args) throws Exception { ArrayList<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); list.add("ccc"); list.add("ddd"); Class<?> clazz = Class.forName("java.util.ArrayList"); //获取字节码文件 Method m = clazz.getMethod("add", Object.class); //获取方法 m.invoke(list, 1111); //执行方法 m.invoke(list, true); System.out.println(list); } } 
(2)具有相同的维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。

代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class。

基本类型的一位数组可以被当作Object类型使用,不能被当做Object[]类型使用,非基本类型数组,既可以当作Object类使用,又可以当作Object[]类型使用.

Arrays.asList()方法处理int[]和String[]时的差异

Array工具类可以完成对数组的反射。

[java] view plaincopyimport java.lang.reflect.Array; import java.util.Arrays; public class Demo { public static void main(String[] args) { int[] a1=new int[]{1,2,3}; int[] a2=new int[3]; int[][] a3=new int[2] [3]; String[]a4=new String []{"a","b","c"}; Object aObj1=a1; Object aObj2=a4; Object[] aObj3=a1; Object[] aObj4=a3; Object[] aObj5=a4; System.out.println(a1); System.out.println(a4); System.out.println(Arrays.asList(a1)); System.out.println(Arrays.asList(a4)); printObject(a4); printObject("xyz"); } private static void printObject(Object obj) { Class clazz =obj.getClass(); if(clazz.isArray()){ int len=Array.getLength(obj); for(int i=0;i<len;i++){ System.out.println(Array.get(obj, i)); } }else{ System.out.println(obj); } } } 

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 抓不住温暖我能怎么办 父亲打母亲我该怎么办 父亲对母亲家暴怎么办 摊上家暴的父亲怎么办 家暴警察不处理怎么办 父亲把母亲打了怎么办 u盘的文件打不开怎么办 头撞墙起包了怎么办 儿童头撞墙起包怎么办 头撞墙了鼓包了怎么办 北京65岁老年证怎么办 怎么办65岁免费乘车卡 5个月小孩晚上哭怎么办 婴儿要含奶头睡怎么办 我把输入法删了怎么办 头发干枯毛躁怎么办用什么洗发水 落枕后脖子歪了怎么办 睡觉睡得脖子疼怎么办? 婴儿脖子睡歪了怎么办 怀孕8个月肚皮痒怎么办 怀孕大阴唇肿了怎么办 孕妇肚皮撑的疼怎么办 我大阴唇特别长怎么办 切完洋葱辣眼睛怎么办 下昆山车没刷卡怎么办 高德地图用不了怎么办 玩游戏老是闪退怎么办 苹果平板电脑闪退怎么办 钉钉忘记打卡了怎么办 钉钉手机号换了怎么办 玖富叮当贷逾期怎么办 玖富超能怎么办现金贷 包包的油边开裂怎么办 lv包包油边开裂怎么办 lv钱包油边开裂怎么办 德运奶粉没勺子怎么办 音响坏了没声音怎么办 6s蓝牙无法配对怎么办 魅族耳机进水了怎么办 苹果6耳机进水了怎么办 耳机内部线坏了怎么办