java基础开发(七)

从今天开始,我们将学习java语言中稍微高级的知识点。

进程与线程


进程:是程序(任务)执行过程,持有的资源和线程。

线程:线程是系统执行的最小单元,同一个进程中有多个线程,线程共享进程的资源。

线程交互方式

  1. 互斥
  2. 同步

java中线程的展示

  • 类   thread
  • 接口  runable



停止java线程

错误方法:stop。调用这个方法缺点就是线程戛然而止,突然停止,不知道执行到哪。所以不建议用。

正确方法,在线程中,使用停止标志,控制线程循环。

争用条件

当多个线程同时共享访问同一个数据,每个线程都尝试操作数据,从而导致数据的破坏。如何解决这个问题,要保证每一个线程访问临街数据时,其他线程不能访问,当访问完,通过某个通信机制,告诉其他线程,它做完了。

通过synchronized关键字来实现互斥,通常我们开锁是需要耗费内存资源,所以不要经常开锁,当缺少某些条件的时候,我们采取的方法,可以用while来判断。其中用object.wait().最后执行完之后,可以采用notifyall,来实现了同步的。

wait,notify,notifyll都是object的方法。

java io

文件说到底,还是对字节的操作,一个字节8位,一个字节可以换算成十进制整数,所以可以当做整数处理或者字节数组。

gbk编码:一个中文汉字占两个字节,一个英文字母占一个字节。
utf-8编码:一个中文汉字占3个字节,一个英文字母占一个字节。
java编码:中文和英文字母都是占两个字节。

需要注意的一个字符串按某种编码变成字节码,字节码变成字符串,也必须按照这种编码,否则就是乱码。

file 可以表示文件或者目录

file只能用于获取文件的名称,大小,不可以访问文件内容。
 		File file = new File("liujinxin.txt");//创建文件,带文件名
		   try {
			file.createNewFile();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}//创建文件
		   file.getAbsolutePath();//获取文件或者目录的绝对地址。
		   file.getName();//获取文件名字
		   file.isFile();//判断是否是文件
		   File file1 = new File("E:"+File.separator);//创建目录地址,这里需要注意的就是File.separator,不管在任何平台都认识
		   file1.isDirectory();//判断是否是目录
		   file1.getName();//获取目录名
		   System.out.println(file1.exists());//判断文件或者目录是否存在
		   System.out.println(file1.mkdir());//创建目录
		   System.out.println(file1.delete());//删除文件或者目录
		   file.getParent();//获取文件和目录的父类

目录遍历

	   File file2 = new File("E:"+File.separator);
		   if(file2.isDirectory()){
			 String[] filename = file2.list();//需要注意这里是返回当前目录下所有子
			 //目录的名字,缺点,如果子目录下还有目录就不能遍历
		   }
		   
		   if(file2!=null&file2.length()>0){
			   if(file2.isDirectory()){
				   File[] file3 = file.listFiles();//虽然这里也是返回子目录的目录对象,但是
				   //但是由于这返回的是对象,可以在进行递归遍历。
				   for(File file4:file3){//遍历file3的所有对象
					   if(file4.isDirectory()){
						   listdirectory(file4);//在次递归调用方法,进行遍历
					   }else{
						   System.out.println(file4);
					   }
					   
				   }
			   }
		   }
		   

RandomAcessFile

可以对文件内容访问,即可对文件读,也可以写。特点可以随机访问文件,即可以访问文件任意位置。

 		   RandomAccessFile raf = new RandomAccessFile(file2, "rw");//后面参数对文件操作模式,rw代表可读可写
		   raf.writeInt(13);
		   byte[] b = new byte[(int) (raf.length())];
		   raf.read(b);
		   System.out.println(b);

io流

分为:输入流(用来读的操作),输出流(用来写的操作)。字节流,字符流。

抽象类
  • inputstream   实现类   fileinputstream
  • outputstream  实现类   fileoutputstream
对于字节流文件操作操作,读到eof=-1,表示文件读取完毕。


网络编程


网络中两台主机互联的条件


  • 两台主机地址,就是ip
  • 互联的主机必须有相同的协议,否则无法沟通
  • 不同主机多个应用程序的相互通信,每一个应用都有唯一的端口号,所以要使用端口号区分

InetAddress

这个类用于标识网络上硬件资源。

 		   InetAddress adress = InetAddress.getLocalHost();//获取本机的Inetadress实例
		   String name = adress.getHostName();//获取本机名字
		   String ip = adress.getHostAddress();//获取本机的ip地址
		   
		   InetAddress otheradress = InetAddress.getByName(name);//根据其他主机名字获取实例
		   String name = adress.getHostName();//获取其他主机名字
		   String ip = adress.getHostAddress();//获取其他主机的ip地址
		   
		   InetAddress adress  = InetAddress.getByName(ip);//可以根据ip地址来获取主机信息

url

统一资源定位符

  		   URL url = new URL("http://wwww.baidu.com");//创建url实例
		   String  protocol= url.getProtocol();//获取url协议
		   String host = url.getHost();//获取url主机名
		   int port = url.getPort();
		   String query = url.getQuery();//返回url带的参数的查询语句。

利用url访问html内容

  		   URL url1 = new URL("http://www.baidu.com");
		   InputStream in =  url1.openStream();//获取url的输入流
		   InputStreamReader ins = new InputStreamReader(in);//将字符流转成字节流
		   BufferedReader br = new BufferedReader(ins);
		   String data = br.readLine();
		   while(data!=null){
			   System.out.println(data);
			   data = br.readLine();
		   }
		   br.close();
		   ins.close();
		   in.close();

socket

  • tcp 面向连接,可靠,有序的字节流。
基于tcp的socket通信


客户端

			try {
				Socket s = new Socket("ip",8888);//指定服务器的IP地址和端口号
				OutputStream os = s.getOutputStream();
				PrintWriter pw = new PrintWriter(os);
				pw.write("内容");
				s.shutdownOutput();//关闭输出流
				pw.flush();//刷新缓冲,输出
				pw.close();
				os.close();
				s.close()
			} catch (UnknownHostException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}


服务端

try {
		ServerSocket  ss = new ServerSocket(8888);//创建服务器的socket,指定端口
		Socket s = ss.accept();//接受客户端连接,返回一个socket对象,accept是阻塞方法,会一直等待客户端的连接。
		InputStream in =  s.getInputStream();//获取字节输入流
		InputStreamReader ins = new InputStreamReader(in);//将字节输入流包装成字符流
		BufferedReader bf = new BufferedReader(ins);//将字符流添加到缓冲区
		String info = bf.readLine();
		while(info!=null){
			System.out.println(info);
			info = bf.readLine();
		}
		s.shutdownInput();//关闭输入流
		s.close();
		bf.close();
		ins.close();
		in.close();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}

如果多个客户端来访问服务器,采用的方法就是多线程。

注意上面shutinput,shutoutput方法,是关闭一次流操作,在执行下一次流操作。
  • 基于udp的socket
服务器端
		try {
			DatagramSocket ds = new DatagramSocket(8888);//创建服务器端的
			//datagramsocket,并指定端口
			byte[] b = new byte[2048];//读取客户端的数据,并保存在数组中
			DatagramPacket packet = new DatagramPacket(b, b.length);//指定数据包的大小
			ds.receive(packet);//阻塞方法,等待客户端的数据包
			String info = new String(b, 0, packet.getLength());
			System.out.println(info);
			
			
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

客户端
 		try {
			InetAddress adress = InetAddress.getByName("");
			int port = 8888;
			byte[] b ="内容".getBytes();
			DatagramPacket packet = new DatagramPacket(b, b.length,adress, port);
			DatagramSocket socket = new DatagramSocket();
			socket.send(packet);
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

java反射

类是对象,类是java.lang.class对象。

Class不能创建对象,只能由jvm创建。


我们可以说任意一个类都是Class对象,有三种表达方式
public class Class1 {
   public static void main(String[] args) {
	   Fu fu  =new Fu();
	 1.  Class c1 = Fu.class; //知道类名,
	 2.  Class c2 = fu.getClass(); //通过Fu的对象来获取
	 3.  Class c3 = null;
	   try {
		c3 = Class.forName("com.example.java.Fu");//类的全称
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	   
	   //c1 c2都是成为Fu的类类型
	   System.out.println(c1==c2);//一个类只能有一个类类型。
	   System.out.println(c2==c3);
	   
	   try {
		Fu fu1 = (Fu) c1.newInstance();//可以通过类类型去创建该类的实例对象
	} catch (InstantiationException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IllegalAccessException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
}
class Fu{
	
}

加载类

编译时加载类是静态加载类,运行时加载类是动态加载类。

静态加载类

	   Fu fu  =new Fu();

new对象,就是静态加载,在编译的时候就需要加载所需要的类,否则,不能运行。

动态加载类

public class Office {
    public static void main(String[] args) {
    	Class c = null;
		try {
			c = Class.forName(args[0]);//获取类类型
			Workutil wu = (Workutil) c.newInstance();//通过类类型获取该类的实例对象
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

public interface Workutil {//制定接口实现规范
     void work();
}
public class Ppt implements Workutil {

	public void work() {
		// TODO Auto-generated method stub
		System.out.println("ppt开始工作啦");
	}
	

}

public class Excel implements Workutil {

	public void work() {
		// TODO Auto-generated method stub
		System.out.println("excel开始工作啦");
		
	}

}

动态加载功能类的功能,我们应该选择动态加载方法,这样实现起来,功能可以进行相应的增加

获取类的方法信息

	   Class c =  obj.getClass();//获取obj的类类型对象
	   System.out.println(c.getName());//返回所有类的方法。
	   Method[] m =   c.getMethods();//这个获取的方法,包括是继承父类的
	   // c.getDeclaredMethods();//这个获取方法只是自己申明的方法,不包括继承的。
	   for(int i = 0;i<m.length;i++){
		  System.out.println(m[i].getName());//返回每一个返回名字
		  Class returntype = m[i].getReturnType();//获取方法的返回的类型
		  System.out.println(returntype.getName());//答应返回值类型
		  Class[] paratyp =  m[i].getParameterTypes();//返回参数类型的类类型的数组
		 for(Class para :paratyp){
			 System.out.println(para.getName());//打印每一个参数类型
		 }
		 
	  }
   

获取类的成员变量信息

 	      public void getClassField(Object obj){
	      Class c1 = obj.getClass();
	      Field[] field =  c1.getFields();//获取所有public方法
	      //c1.getDeclaredFields();获取所有申明的方法
	      for(int i = 0;i<field.length;i++){
	    	  String filename = field[i].getName();//获取字段的名字
	    	  Class fileldtype = field[i].getType();//获取字段类型
	      }
   }

获取类的构造方法

		public void getClassCon(Object obj){
	     	Class c2 = obj.getClass();
	        Constructor[] constructor  =  c2.getDeclaredConstructors();//获取该类的自己申明构造函数的类类型
	        for(int i = 0;i<constructor.length;i++){
		  String constructorname =  constructor[i].getName();
		  Class[] constructorparatype = constructor[i].getParameterTypes();//获取该类的构造函数的参数的类类型的数组
		  for(Class contparaype: constructorparatype){
			 String paraname = contparaype.getName();//获取构造函数的参数名字
		  }
	   }
   }

如何获取某个方法

方法对的方法名和参数列表唯一决定了该方法。
public class TestMethods {
	public static void main(String[] args) {
		A a = new A();
		Class c = a.getClass(); //获取A的类类型
		//a.print(10, 20);//调用方法
		Method m;
		try {
			m = c.getDeclaredMethod("print", int.class,int.class);//传入方法的方法名,后面是方法的参数的类类型
			m.invoke(a, 10,20);//通过放射调用方法,第一变量是操作的方法的对象,后面是参数的参数类型
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
		
	}
	

}
class A{
	public void print(int a,int b){
		System.out.println(a+b);
	}
	
}

通过反射来认识泛型

	public static void main(String[] args) {
		 List list = new ArrayList();
		 list.add(1);//这个list可以添加任意集合
		 List<String> list1 = new ArrayList<String>();
		 list1.add("liu");//只能添加字符串集合
		 //结论:泛型是防止数据的错误输入,在编译前有效,绕过编译就无效。
		 
		 Class c = list1.getClass();
		 try {
			Method m = c.getDeclaredMethod("add", int.class);
			m.invoke(list1, 132);//这样就可以将整型添加进去
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 
	}




































































































































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值