Learning_java300

在这里插入图片描述
begin:2018/10/17
参考文章:

eclipse不能查看源码
注:jdk源码在C:\Program Files\Java\jdk1.8.0_161\zip.rar

JAVA版本分类:

javaSE Java standard Edition 标准版
javaEE Java enterpaise Edition 企业版
javaME Java Micro Edition 微型版(消亡,被安卓取代)

java特点:

核心:跨平台,比如int永远32位
安全、面对、简单(入门)、高性能、分布式、多线程、健壮性

运行机制:

编译和解释结合,将java程序编译为字节码,然后通过jvm与底层连接

JVM、JRE、JDK的区别:

JVM(java virtual machine):虚拟机,用于执行字节码
JRE(java runtime environment) :包含java虚拟机、库函数、运行java应用所必须的文件
JDK(java development kit):包含JRE,以及增加编译器和调试器等用于程序开发的文件

java环境配置:

百度,用eclips开发

java程序实例:

Welcome程序:

public class Welcome{
	public statitc void main(String[] args){
		System.out.println("hard working!")}
	}
//保存:Welcome.java   
//运行:javac  Welcome.java
			java   Welcome

  • 每个语句必须以分号结束,回车不是语句结束标志
  • 一个文件可以有多个类,但只能有一个public

第一个桌球小项目:(源代码运行起来有问题,可能跟系统有关,先体会怎么编程)

import java.awt.*;
import javax.swing.*;

public class BallGame2  extends JFrame {
	Image ball = Toolkit.getDefaultToolkit().getImage("image/ball.png");
	Image desk = Toolkit.getDefaultToolkit().getImage("image/desk.png");
	
	double x = 100;//ball横坐标;
	double y = 100;//ball纵坐标;
	double degree = 3.14/3; //弧度,指60度

	
	//画窗口的方法;
	public void paint(Graphics g) {
		System.out.println("窗口被画了一次");
		g.drawImage(desk, 0, 0, null);
		g.drawImage(ball, (int)x, (int)y, null);//强制类型转换;
		
		x = x + 10*Math.cos(degree);
		y = y + 10*Math.cos(degree);
		
		if(y > 500 || y < 80) {
			degree = -degree;
		}
		
		if(x < 0 || x > 856) {
			degree = 3.14 - degree;
		}
		
	
		
		
	}
	
	//窗口加载;
	void launchFrame() {
		setSize(856,500);
		setLocation(50,50);
		setVisible(true);
		//重画窗口;
		while(true) {
			repaint();//调用paint;
			try {
				Thread.sleep(40);
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	//main 程序执行入口
	public static void main(String[] args) {
		System.out.println("寓教于乐");
		BallGame2 game = new BallGame2();
		game.launchFrame();
	}

}

  • 类起名,首字母大写 Man 、GoodMan
  • 方法和变量,第一个单词小写,第二个首字母大写“驼峰原则”
  • 变量的本质是一个“可操作的存储空间”

局部变量,从属于方法
成员变量,从属于对象
静态变量(static修饰),从属于

第二个小代码:Student类


public class Student {
	String name;//属性,只有属性的类叫做结构体stucture;
	int age;
	String school;
	
	Computer comp;//外部类;
	
	
	void myself() {      //方法;                     
		System.out.println("我是:"+ name);
	}
	void study() {
		System.out.println("我在使用电脑: "+comp.brand);
	}
	

	public static void main(String[] args) {
		Student stu = new Student();
		stu.name = "pingan";
		stu.age = 23;
		stu.school = "nupt";
		
		Computer c1 = new Computer();
		c1.brand = "MAC";
		
		stu.comp = c1; //Computer对象赋值给stu;
		
		stu.myself();
		stu.study();		
		
	}

}

//要定义在Student外部;
class Computer{
	String brand;
}

/**输出:
我是:pingan
我在使用电脑: MAC

JVM内存模型

栈:

  1. 栈描述的是方法执行的内存模型,每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)
  2. JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)
  3. 栈属于线程私有,不能实现线程间共享
  4. 先进后出
  5. 系统自动分配。速度快,是一个连续的内存空间

堆:

  1. 用于存储创建好的的对象(new)
  2. JVM只有一个堆,被所有线程共享
  3. 不连续的空间,分配灵活,速度慢

方法区:

  1. JVM只有一个方法区,被所有线程共享
  2. 实际上也是堆,只是用于存储类、常量相关的信息
  3. 用来存储程序中永远不变或者唯一的内容(类信息、class对象、静态变量、字符串常量等)

画Student类的内存模型:
在这里插入图片描述

static关键字:

关于Java中的static关键字

用static修饰的成员变量/方法叫静态成员变量/方法,也叫类变量/方法,其生命周期和类相同。静态变量/方法都存放在方法区
也就是说,Java中的 static 关键字主要是用来做内存管理的。

super关键字:

用super访问父类被子类覆盖的属性或方法
super()永远位于构造器的第一句(默认)-继承树追溯,就是说子类必须实现父类的方法。Child–>Father–>Object

封装:

在这里插入图片描述

javaBean原则:

  • 属性一律private;
  • 提供相应的获取和改造属性的方法,如setName,getName(权限为public)
public void setName(String name){
		this.name = name;
	}
public void getName(String name){
		return this.name;
	}

多态:

子类重写父类的方法:


public class PolyTest {
	
	public static void main(String[] args) {
		Animal A = new Animal();
		A.shout();
		
		Dog D = new Dog();
		D.shout();
		Cat C = new Cat();
		C.shout();
	}

}

class Animal{   //class 后面没有()啊!!!!
	public void shout() {
		System.out.println("sing a song");
	}
}


class Cat extends Animal{
	public void shout() {
		System.out.println("miao");
	}
}

class Dog extends Animal{
	public void shout() {
		System.out.println("wang");
	}
 }

对象的转型:

可以向上转型,用的时候可以强制转回来,但是不同类型的对象不能强制转型

    Animal  d = new Dog(); //Dog转为Animal,可以想上转型;
    Dog d2 = (Dog)d//强制转回来;

    Animal  d = new Cat(); //Cat转为Animal,可以想上转型;
    Dog d3 = (Dog)d//强制转为Dog,编译器会报错,java.lang.ClassCastException;
   	

final关键字:

  • 修饰变量:不可改变
  • 修饰方法:可被重载,但不可被子类重写
  • 修饰类:不可被继承,比如Math、String等

多态的内存分析

注意点:

  • 最开始的时候,java Test,这个Test的类也要写在方法区
  • 方法区是加载类的代码、静态变量/方法、字符串常量的
  • new创建cat时候,因为是多态继承的,所以要写出Cat–>Animal–>Object的框
  • this 指向对象,就是最外层包围的
public static void main(String[] args){
	Animal a = new Cat();
	Cat a2 = (Cat)a;
	testAnimalVoice(Voice(a));
	}

在这里插入图片描述

抽象类(abstract class)

为什么需要抽象类:

  • 是一种模板模式,为所有的子类提供一个通用模板,子类在此基础上进行扩展
  • 避免了子类设计的随意性

要点:

  • 有抽象方法的类只能定义为抽象类(abstract方法,然后必须在class前面也加abstract)
  • 不能实例化,就是不能new了
  • 可以包含属性、方法、构造方法
  • 只能用来继承
  • 必须被子类实现
  • 抽象类里面可以包含非抽象方法
  • 在类的非抽象方法里可以包含抽象方法,因为this.方法,这个this指向的是子类已经被实现的抽象方法

接口(interface)

  • 比抽象类更抽象,不能包含非抽象类
  • public static final 常量定义,默认
  • public abstract 定义方法,默认
  • 接口支持多继承
public interface MyInterface(){
	/*public static final 常量定义,默认*/ String NAME = "boss”;
    int MAX_NUMBER = 123;
	//方法必须私有;
	/*public abstract*/public void test();
	public int test01(int a,int b);	

public class Cat  implements  Animal{}
//多继承
public interface C extends A,B{}

回调(CallBack、Hook)

将代码的某一部分分离出来,在其他的地方再加上一些东西嵌入进去

package cn.nupt;

public class Test {
	
	public static void drawFrame(Myframe f) {
	System.out.println("1");
	System.out.println("2");
	System.out.println("3");
	System.out.println("4");
	f.say();
	System.out.println("5");
	System.out.println("6");
	System.out.println("7");
	}
	
	public static void main(String[] args) {
	   drawFrame(new Frame01());
	}
 }


	 class Frame01 extends Myframe  {
		public void say() {
			System.out.println("Frame01");		
		}	
	}
	
	
	 class Frame02  extends Myframe {
		public void say() {
			System.out.println("Frame02");		
		}	
	}

public  abstract class Myframe {
	public void say ();
}

内部类(innerclass)

作用:

  • 提供更好的封装,可以让外部类直接访问,不允许同一个包中的其他类直接访问
  • 内部类可以直接访问外部类的私有属性,外部类不能访问内部类的内部属性(“脸”不能呼吸,只能“鼻子”来呼吸,不能“脸.呼吸”,只能“脸.鼻子.呼吸”)
  • 静态成员不能访问非静态成员(静态从属于类,非静态从属于对象)
  • 非静态成员不能有静态属性/方法/初始化块

分类:

  • 成员内部类:非静态内部类/静态内部类
  • 匿名内部类:new 父类构造器(实参列表)实现接口(){}(适合只需要使用一次的类)

StringBuilder 和StringBuffer

String:不可变字符串
StringBuilder 和StringBuffer:可变字符串(主要用StringBuilder )

ArrayList类详解

ArrayList就是动态数组

容器Collection类

分类:

list:有序,可重复
ArrayList:底层实现是数组 、线程不安全,效率高,查询快,修改,插入、删除慢
LinkList:底层实现是链表,线程不安全,效率高,查询慢,修改、插入、删除快
Vector 线程不安全,效率低
set:无序,不可重复
map:键值对

java网络编程:

在这里插入图片描述

UDP编程

在这里插入图片描述

java异常

java异常

try-catch-finally
throws/throw

IO流

在这里插入图片描述

分类:

  • 字节流:0-255整数,数字数据、可执行的程序、internet通信、字节码
  • 字符流:只能处理文本数据

步骤:

  1. 创建一个与数据源或数据目的地相关联的流
  2. 将一个过滤器和流关联起来
  3. 通过过滤器(而不是流)来传输

相关异常:


 FileNotFoundException/EOFException  extends  IOException

字节流相关类:

FileInputStream/FileOutputStream   extends  InputStream  //主要用到
DataInputStream/DataOutputStream  extends  InputStream //好像没怎么用

文件流:构造函数:FileInputStream(String)里面写上文件名,

比如:

FileInputStream file  = new FileInputStream("D:\\data\\test.py")

也可以用File类的属性separator 就是分隔符,不区分系统

char  sep  = File.separator;
FileInputStream("D:" + sep +"data" + sep + "test.py")
注:try(){}---catch--finally    [try中的()有什么用?](https://blog.csdn.net/llkoio/article/details/78939148?utm_source=blogxgwz0)
try(){   //此处的try(){}括号中的一般是资源申请,实现了implement  closeable   的类,就不用再加finally了,自动.close/.
}catch(IOException e){
}finally{
}

来一个小列子:读取一个图片

package cn.wuxi;

import java.io.FileInputStream;
import java.io.IOException;

public class IoStreamTest {
	
	public static void main(String[] args) {
		try(FileInputStream file = new FileInputStream("C:\\Users\\pingan\\Pictures\\Saved Pictures\\112.jpg"))
		{   boolean eof = true;   
	        int count = 0;
	        while(eof) {
	        	
	        	int a = file.read();
	            System.out.println(a + " //");
	            
	        	////////////////////////////////		
	        	if(a == -1) 
	        		eof = false;
	        	else
	        		count ++;
	        	
	        }
	       System.out.println(count );
	       file.close();	
		}catch(IOException e ) {
			System.out.println(e.toString());
		}
	}

}

再尝试将FileInputStream 对象read后用FileOuputStream write写入

package cn.wuxi;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class IoStreamTest {
	public static void main(String[] args) {
		
		try(
		FileInputStream filein = new FileInputStream("C:\\Users\\pingan\\Pictures\\Saved Pictures\\112.jpg");
		FileOutputStream fileout = new FileOutputStream("C:\\Users\\pingan\\Pictures\\Saved Pictures\\114.jpg"))  {
		boolean eof  =  true ;
		while (eof) {
			int a = filein.read();
			 fileout.write(a) ;
			 if(a == -1)
				 eof = false;		 
		}
		filein.close();	//是在try - catch 之间;
		fileout.close();
		
	} catch (IOException e) {
		System.out.println(e.toString());
	}
 }

}

为什么read方法返回的是int,而不是byte?

答:在用输入流读取一个byte数据时,有时会出现连续8个1的情况,这个值在计算机内部表示-1,正 好符合了流结束标记。所以为了避免流操作数据提前结束,将读到的字节进行int类型的扩展。保留该字节数据的同时,前面都补0,避免出现-1的情况。

字符流:

字符流相关类:

FileReader  extends  InputStreamReader

具体操作和字节流一样

序列化和反序列化的概念

序列化和反序列化

  • 把对象转换为字节序列的过程称为对象的序列化。
  • 把字节序列恢复为对象的过程称为对象的反序列化。

对象的序列化主要有两种用途:
  1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
  2) 在网络上传送对象的字节序列。

在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。
  当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。
  
也就是说,一方面我们要将数据永远存储到硬盘上,另一方面是将对象 序列化传输,将数据表示为对象,而不是之前的外部格式,每次用到都要转化为 类可以使用的格式

序列化需要实现相关接口:
Serializable 不包含任何必须实现的方法,唯一用途是:指出类对象可以以串行方式存储和检索
对象通过类ObjectOutputStream的writeObject方法写入到流中
对象通过类ObjectIntputStream的readObject方法将对象从序列中读出

//序列化对象
ObjectOutputStream oo  == new ObjectOutputStream(new  FileOutputStreamnew File("E:/Person.txt")));
oo.writeObject(需要序列化的对象);
//反序列化对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("E:/Person.txt")));
Person person = (Person) ois.readObject();//将文件中的序列变成对象,强制转换

猜你喜欢

转载自blog.csdn.net/weixin_39782583/article/details/83112651
300