Java学习笔记1

三高问题:高可用、高性能、高并发
计算机软件:(1)系统软件:DOS(Disk Operating System), Windows, Linux, Unix, Mac, Android, IOS;(2)应用软件:WPS、QQ……

1. Java基础

1.1 数据类型

强类型语言:
要求变量的使用要严格符合规定,所有变量都必须先定义后才能使用。

1 B(byte,字节)=8 bit(位)
1024B=1KB
1024KB=1M
1024M=1G
电脑32位(4GB)和64位(128GB)表示其寻址能力

Java的数据类型:

  • 基本类型primitive type:
    • 数值:整数(byte127_1B、short32767_2B、int_4B、long+L_8B)、浮点(float+F_4B、double_8B)、字符(char_2B)
    • Boolean类型_1bit
  • 引用数据类型Reference Type:
    • 接口
    • 数组

拓展:

  1. 进制:二进制0b、八进制0、十六进制0x 0-9A-F。
  2. 银行业务用BigDecimal数学工具类,最好不要使用浮点数进行比较,因为float是有限、离散的,存在舍入误差,其结果为一个接近但不等于的值。
  3. 所有字符本质是数字。Unicode表:0-65536(97=a、65=A);’\u0061’。
  4. JDK7新特性,数字之间可以用下划线分割,如10_0000_0000。

数据转换:
由低到高:byte\short\char -> int -> long -> float -> double
运算中,不同类型的数据先转换为同一类型,然后进行运算。

  • 强制转换: (类型)变量名 高—>低
  • 自动转换: 低—>高
    注意:不能对布尔值进行转换;不能把对象类型转换为不相干的类型;高容量转换为低容量时强制转换,但有内存溢出或精度问题。

1.2 变量

type varName [=value] [{,varName[=value]}];
//每个变量都有类型,可以是基本类型或引用类型
  • 类变量,static,静态的,从属于类;
  • 实例变量,从属于对象,如果不初始化,则为其类型的默认值0/0.0/u0000/False/null;
  • 局部变量,必须声明和初始化值。

1.3 常量

修饰符不存在先后顺序。

final 常量名=;

1.4 变量命名规范

  1. 类成员变量、局部变量:首字母小写和驼峰原则;
  2. 常量:大写字母和下划线:MAX_VALUE;
  3. 类名:首字母大写和驼峰原则:GoodMan;
  4. 方法名:首字母小写和驼峰原则:runRun()。

运算符instanceof
Ctrl+D:复制当前行到下一行
Ctrl+/快速注释
Ctrl+Alt+T选中代码自动包裹进方法里
项目结构-Modules-add content root-out输出目录里的class文件
取余%(模运算)
Math.pow(幂运算)
A^B(异或)二进制位相同为0,不同为1(不进位的相加)
<< *2; >> /2(位移运算)效率高!
三元运算符 ? :

//自增、自减 一元运算符
int a = 3;
int b = a++; //先给b赋值,再自增
int c = ++a; //先自增,再赋值

//短路运算
int c = 5;
boolean d = (c<4)&&(c++<4); //自增不执行
System.out.println(d);
Systen.out.println(c);

//字符串连接符 +,String
int a = 10;
int b = 20;
System.out.println(""+a+b); //1020 先转换再计算
System.out.println(a+b+""); //30 先计算再转换

1.5 包机制

用于区别类名的命名空间。

package pkg1[.pkg2[.pkg3...]]; //必须打头
import package1[.package2...].(classname|*);

一般利用公司域名倒置作为包名:com.baidu.www

1.6 JavaDoc

用来生成自己API文档。
参数信息:

  • /** @author @version @since @param @return @throws

CMD: javadoc -encoding UTF-8 -charset UTF-8 Doc.java
作业:使用idea生成Javadoc

2. Java流程控制

2.1 用户交互Scanner

java.util.Scanner是Java5的新特征。

Scanner s = new Scanner(System.in);
//凡是属于IO流的类如果不关闭会一直占用资源,所以用完就关掉
s.close()

通过Scanner类的next()【不能空格】与nextLine()方法获取输入的字符串,在读取前我们一般需要使用hasNext()与hasNextLine()判断是否还有输入的数据。

equals:判断字符串是否相等
反编译,找到class文件路径,复制到idea看源码

2.2 switch多选择结构

switch语句中的变量类型可以是:

  • byte、short、int或者char
  • 从Java SE7开始支持字符串String类型
  • case标签必须为字符串常量或字面量
public static void main(String[] args){
	// case穿透
	char grade = 'F';
	switch (grade){ // 匹配一个具体的值
		case 'A':
			System.out.println("优秀");
			break;// 不加break,后面全部输出
		case 'B':
			System.out.println("一般");
		default:
			System.out.println("未知");
	}
}

2.3 while循环

少部分情况需要循环一直执行,比如服务器的请求响应监听、定时检查等。如果循环条件一直为true就会造成无限循环(死循环)。

do…while保证循环体至少循环一次。

for(初始化;布尔表达式;更新){//循环次数执行前就确定了
	//代码语句
}

//练习:输出1-1000之间能被5整除的数,并且每行输出3个
for (int i=0;i<=100;i++){
	if (i%5==0){
		System.out.print(i+"\t");
	}
	if (i%(5*3)==0){
		System.out.println();
		//System.out.print("\n");
	}
}
//增强for循环,Java5引入了一种主要用于数组或集合的增强型for循环
for(声明语句:表达式){
/*声明语句:新的局部变量,其类型与数组元素类型匹配,作用域在循环语句块,其值与此时数组元素的值相等。
表达式:要访问的数组名,或者是返回值为数组的方法。*/
	//代码句子
}
//goto——带标签的break和continue,对Java来说唯一用到标签的地方是在循环语句之前
//打印101-150之间所有的质数
int count = 0;
outer: for (int i=101;i<150;i++){
	for (int j=2;j<i/2;j++){
		if (i % j == 0){
			continue outer;
		}
	}
	System.out.print(i+" ");
}
//打印三角形
for (int i = 1; i <= 5; i++) {
	for (int j = 5; j >= i; j--) {
		System.out.print(" ");
	}
	for (int j = 1; j <= i; j++) {
		System.out.print("*");
	}
	for (int j = 1; j < i; j++) {
		System.out.print("*");
	}
	System.out.println();		
}

3. Java方法详解

System类.out对象.println()方法
设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合。保持方法的原子性,一个方法只完成一个功能,有利于后期拓展。

修饰符 返回值类型 方法名 (参数类型 参数名){
	//形式参数:在方法被调用时用于接收外界输入的数据;
	//实参:调用方法时实际传给方法的数据。
	...
	方法体
	...
	return 返回值;//除了返回值以外还可以终止方法
}

值传递:Java是值传递
引用传递

重载就是在一个类中,有相同的函数名称但形参不同的函数。
方法的重载规则:

  • 方法名称必须相同;
  • 参数列表必须不同(个数、类型、排列顺序);
  • 方法的返回类型可以相同也可以不同;
  • 仅仅返回类型不同不足以成为方法的重载;
  • 编译器会根据调用方法的参数个数、类型等去逐个匹配。

命令行传递参数:(main方法传参)
java com.method.demo this is java -unicode utf-8

//JDK1.5支持传递同类型可变参数给一个方法,一个方法只能指定一个可变参数,且在最后
public static void printMax(double... numbers){
	if (numbers.length == 0) {
		System.out.println("No argument passed");
		return;
	}
	double result = numbers[0];
	for (int i = 1; i < numbers.length; i++){
		if (numbers[i] > result) {
			result = numbers[i];
		}
	}
	System.out.println("The max value is " + result);
}					

递归结构包括:

  1. 递归头:什么时候不调用自身方法。如果没有头则死循环;
  2. 递归体:什么时候需要调用自身方法。
  3. 栈机制:能不用递归就不用递归,太多会影响性能。
public static void main(String[] args){
	System.out.println(f(n:5));
}
public static int f(int n){
	if (n==1){
		return 1;
	}else{
		return n*f(n:n-1);
	}
}

4. 数组

数组是相同类型数据的有序集合,长度确定。

// 声明数组变量
dataType[] arrayRefVar; // 首选
dataType arrayRefVar[]; // C/C++风格
// 创建数组
dataType[] arrayRefVar = new dataType[arraySize];
// 不赋值为默认值0/null等
// 二维数组
int a[][] = new int[2][5];

4.1 数组的三种初始化

  1. 静态初始化
int[] a = {1,2,3};
Man[] mans = {new Man(1,1),new Man(2,2)};
  1. 动态初始化(包含默认初始化)
int[] a = new int[2];
a[0] = 1;
a[1] = 2;
  1. 默认初始化
    数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。

4.2 内存分析

不存放别的对象引用
含基本类型的具体数值
存放引用在堆的具体地址
内存
方法区
存放new对象和数组
可被所有线程共享
存放基本变量类型
引用对象的变量
可被所有线程共享
含所有class\static变量

4.3 Arrays类

  • 打印数组元素Arrays.toString();
  • 排序升序Arrays.sort();
  • ……

4.4 八大排序算法

冒泡排序(优化)

public static int[] sort(int[] array){
	int temp = 0;
	for (int i = 0; i < array.length-1; i++){
		boolean flag = false;
		for (int j = 0; j < array.length-1-i; j++){
			if (array[j+1] < array[j]){
				temp = array[j];
				array[j] = array[j+1];
				array[j+1] = temp;
				flag = true;
			}
		}
		if (flag == false){
			break;
		}
	}
	return array;
}

4.5 稀疏数组

数组大部分元素为0或同一值的数组。
处理方式:记录数组一共有几行几列,有多少个不同值。

//棋盘存盘及还原
public static void main(String[] args){
	int[][] array1 = new int[11][11];
	int[1][2] = 1;
	int[2][3] = 1;
	for (int[] ints : array1){
		for (int anInt : ints){
			System.out.print(anInt+"\t");
		}
		System.out.println();
	}
	//转换为稀疏数组
	int sum = 0;
	for (int i = 0; i < 11; i++){
		for (int j = 0; j < 11; j++){
			if (array1[i][j] != 0){
				sum ++;
			}
		}
	}
	
	int[][] array2 = new int[sum+1][3];
	array2[0][0] = 11;
	array2[0][1] = 11;
	array2[0][2] = sum;
	
	int count = 0;
	for (int i = 0; i < array1.length; i++){
		for (int j = 0; j < array1[i].length; j++){
			if (array1[i][j] != 0){
				count++;
				array2[count][0] = i;
				array2[count][1] = j;
				array2[count][2] = array1[i][j];
			}
		}
	}
	//还原
	int[][] array3 = new int[array2[0][0]][array2[0][1]];
	for (int i = 1; i < array2.length; i++){
		array3[array2[i][0]][array2[i][1]] = array2[i][2];
	}
}

5. 面向对象编程

面向对象编程的本质:以类的方式组织代码,以对象的组织(封装)数据。

抽象

三大特性:

  • 封装
  • 继承
  • 多态

静态方法static可以直接调用,其和类一起加载;
非静态方法需要new实例化,类实例化后才存在。
值传递:方法传参只传值;
引用传递:通常为对象,但本质还是值传递。
对象是通过引用来操作的:栈–>堆。

使用new关键字创建对象,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。类中的构造器也称构造方法,是在进行创建对象的时候必须要调用的,并且构造器有以下两个特点:

  • Alt+insert快捷键生成构造器;
  • 必须和类的名字相同;
  • 必须没有返回类型,也不能写void。
  • 作用:1.new本质在调用构造器;2.初始化对象的值。
  • 有参构造:一旦定义有参构造,无参就必须显式定义(方法可以重载,根据参数自动判断)。

5.1 封装

封装,数据的隐藏——高内聚、低耦合——应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问。
属性私有,get/set
封装的意义:

  • 提高程序的安全性,保护数据;
  • 隐藏代码的实现细节;
  • 统一接口;
  • 系统可维护性增加。

5.2 继承

Java中只有单继承,没有多继承。

修饰符:public > protected > default > private。
Ctrl+H快捷键,打开继承树。
final修饰的类不能被继承。

私有属性和方法无法继承。
super()显式地调用父类的构造器,必须要在子类构造器的第一行。
super()必须只能出现在子类的方法或者构造方法中。
super和this不能同时调用构造方法。

VS this:

  • 代表的对象不同:this-本身调用者这个对象;super-父类对象的应用;
  • 前提:this-没继承也可以使用;super-只能在继承条件下使用;
  • 构造方法:this-本类的构造;super-父类的构造。

5.2.1 重写

重写都是方法的重写,和属性无关。 区别于重载

//静态方法:方法的调用只和左边定义的数据类型有关。
//非静态方法:子类重写了父类的方法。
//父类的引用指向了子类
B b = new A(); // 输出B而非A
  • 方法名必须相同;
  • 参数列表必须相同;
  • 子类不一定需要或者不一定满足——方法体不同;
  • 修饰符:范围可以扩大但不能缩小:public>protected>default>private
  • 抛出的异常:范围可以缩小,但不能扩大:ClassNotFoundException
  • 不能重写的方法:1.static方法,属于类,不属于实例;2.final常量;3.private方法。

5.2.2 多态

即同一方法可以根据发送对象的不同而采用多种不同的行为方式。
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多。
多态是方法的多态,属性没有多态性。
多态存在的条件:1.继承关系;2.子类重写父类方法;3.父类引用指向子类对象。

Person s = new Student();//父类引用指向子类对象,但不能调用子类独有的方法。
((Student) s).eat();//强制类型转换,高转低,可调用子类独有方法

5.3 Static关键字详解

类中的静态变量可被多个实例共享,通过类名调用或者对象调用。

{
	//代码块(匿名代码块)
	//不主动调用,创建对象时在构造器之前自动执行
}
static {
	//静态代码块
	//类一加载就执行,永久只执行一次
}
//执行顺序:1.静态代码块;2.匿名代码块;3.构造方法

//静态导入包
import static java.lang.Math.random; // 导入这个方法,直接写random()

5.4 抽象类(约束)

abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法则是抽象方法,如果修饰类则是抽象类。
抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。

抽象类不能使用new关键字来创建对象,它是用来让子类继承的。
抽象方法只有方法的声明,没有方法的实现,它是用来让子类实现的。

子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。

问题:

  1. 存在构造器吗?
  2. 其意义是什么?提高开发效率,减少重复代码

5.5 接口

接口可以伪多继承。

普通类:只有具体实现
抽象类:具体实现和规范(抽象方法)都有
接口:只有规范,自己无法写方法,不能被实例化——约束和实现分离:面向接口编程

接口就是规范,定义的是一组规则,体现了现实世界中“如果你是…则必须能…”的思想。接口的本质是契约,制定好后大家都遵守。
OO的精髓是对对象的抽象,接口最能体现这一点。

声明类的关键字是class,声明接口的关键字是interface

  • 接口中的所有定义的方法都是抽象的public,public、abstract都可省略;
  • 接口中的所有定义的属性都是常量public、static、final,一般不定义;
  • 接口都需要实现类implements,重写接口中的方法override;
  • 接口的作用:1.约束;2.定义方法由多人实现。

5.6 N种内部类

内部类就是在一个类的内部再定义一个类,比如A类中定义一个B类,B类就是A类的内部类,A类是B类的外部类。

  • 成员内部类
public class Outer{
	private int id = 10;
	public void out(){
		System.out.println("这是外部类的方法");
	}
	public class Inner{
		public void in(){
			System.out.println("这是内部类的方法");
		}
		public void getID(){
			System.out.println(id);//可以访问外部类的私有属性(重要)
		}
	}
}
public class Application{
	public static void main(String[] args){
		Outer outer = new Outer();
		Outer.Inner inner = outer.new Inner();
		inner.getID();
	}
}
  • 静态内部类
...
	public static class Inner{
		public void in(){
			System.out.println("这是内部类的方法");
		}
		/*
		public void getID(){
			System.out.println(id);
			//不能访问,静态类比非静态属性先加载
		}*/
	}
...
  • 局部内部类
    方法里写类
  • 匿名内部类
    没有名字初始化类,不用将实例保存到变量中。

一个Java文件里只能有一个public class类,但可以有多个class类

6. 异常机制

  • 检查性异常
  • 运行时异常
  • 错误ERROR

基类java.lang.Throwable:

  • Error
    由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关,JVM一般会选择终止线程。
  • Exception
    运行时异常,一般由程序逻辑错误引起的。

抛出异常
捕获异常,捕获多个异常要从小到大,否则报错

关键字:try、catch、finally、throw、throws

public void test(int a, int b) throws ArithmeticException{
//假设方法处理不了异常,用throws在方法上抛出异常至更高级别
	if (b==0){
		throw new ArithmeticException();
	}//一般定义在方法里,主动抛出异常
}

Java学习笔记1_第1张图片
自定义异常类,只需继承Exception类即可,步骤如下:

  1. 创建自定义异常类;
  2. 在方法中通过throw关键字抛出异常对象;
  3. 如果在当前抛出异常的方法中处理异常,可用try/catch语句捕获并处理;否则在方法的声明处通过throws指明要抛出给方法调用者的异常;
  4. 在出现异常方法的调用者中捕获并处理异常。

你可能感兴趣的:(编程语言,java,面向对象编程,抽象类)