【Java基础】-【封装】-【类】

面向对象

一、面向过程:当需要实现一个功能时 每一个具体的步骤都要亲力亲为 详细处理每一个细节
二、面向对象:当需要实现一个功能时 不关心具体的步骤 而是找一个已经具有该功能的人来帮我做事
三、面向对象三大基本特征:封装 继承 多态
四、类:是一组相关属性和行为的集合 可以看成是一类事物的模板 使用事物的属性特征和行为特征来描述该类事物

  1. 属性:该事物的状态信息
  2. 行为:该事物能够做什么
    五、对象:是一类事物的具体体现 对象是类的一个实例 必须具备该类事物的属性和行为

六、类与对象的关系:

  1. 类是对一类事物的描述 是抽象的
  2. 对象是一类事物的实例 是具体的
  3. 类是对象的模板 对象是类的实体

七、局部变量和成员变量的区别:

  1. 定义的位置不一样:
    局部变量:在方法内部
    成员变量:在方法的外部 直接写在类当中
  2. 作用范围不一样:
    局部变量:只有方法当中才可以使用 出了方法就不能再用
    成员变量:整个类全都可以通用
  3. 默认值不一样:
    局部变量:没有默认值 如果要想使用 必须手动进行赋值
    成员变量:如果没有赋值 会有默认值 规则和数组一样
  4. 内存的位置不一样:
    局部变量:位于栈内存
    成员变量:位于堆内存
  5. 生命周期不一样:
    局部变量:随着方法进栈而诞生 随着方法出栈而消失
    成员变量:随着对象进栈而诞生 随着对象被垃圾回收而消失

【注】:方法的形式参数是局部变量 该参数在方法调用的时候必然会被赋值的

import java.util.Arrays;
public class PrintArray {
	public static void main(String[] args) {
		int[] array = {10,20,30,40,50};
		//要求打印格式为:[10,20,30,40,50]
		//使用面向过程 每个步骤细节都要亲力亲为
		System.out.print("[");
		for(int i = 0;i < array.length;i++) {
			if (i == array.length - 1) {//如果是最后一个元素
				System.out.println(array[i] + "]");
			}else {//如果不是最后一个元素
				System.out.print(array[i] + ",");
			}
		}
		System.out.println("================================");
		//使用面向对象 找一个jdk给我们提供好的Array类 其中有一个toString方法 直接就能把数组变成想要的格式的字符串
		System.out.print(Arrays.toString(array));
	}
}

类与对象的使用

一、定义一个类 用来模拟“学生”事物 其中有两个组成部分:

  1. 属性(是什么):姓名 年龄
  2. 行为(能做什么):吃饭 睡觉 学习

二、对应到Java的类当中:

  1. 成员变量(属性):
String name;//姓名
int age;//年龄
  1. 成员方法(行为):成员方法最重要的特征是 没有static
public void eat(){}//吃饭
public void sleep(){}//睡觉
public void study(){}//学习

【注】:

  1. 成员变量直接定义在类当中 方法外
  2. 成员方法不要写static关键字
public class Student {
	//成员变量:直接写在class内 方法外的变量
	String name;//姓名
	int age;//年龄
	
	//成员方法
	public void eat(){
		System.out.println("吃饭!");
	}
	public void sleep(){
		System.out.println("睡觉!");
	}
	public void study(){
		System.out.println("学习!");
	}
}

三、通常情况下 一个类并不能直接使用 需要根据类创建一个对象 才能使用

  1. 如何创建对象:
    (1)导包:指出需要使用的类在什么位置
    格式:import 包名称.类名称;
    对于和当前类属于同一个包的情况 可以省略导包语句不写
    (2)创建对象:
    格式:类名称 对象名 = new 类名称();
    (3)使用:
    使用成员变量:对象名.成员变量名
    使用成员方法:对象名.成员方法名([参数])
    也就是想用谁就用对象名.谁

【注】:如果成员变量没有进行赋值 那么将会有一个默认值 规则和数组一样

public class StudentUse2 {
	public static void main(String[] args) {
		//1.导包
		//我需要使用的Student类和我自己位于同一个包下 所以省略导包语句不写
				
		//2.创建:
		//格式:类名称 对象名 = new 类名称();
		//根据Student类创建一个名为stu的对象
		Student stu = new Student();
				
		//3.使用其中的成员变量
		//格式:对象名.成员变量名
		System.out.println(stu.name);//null
		System.out.println(stu.age);//0
		System.out.println("===================================");
		
		//改变对象当中的成员变量数值内容
		//将右侧的字符串赋值交给stu对象当中的name成员变量
		stu.name = "赵丽颖";
		stu.age = 18;
		System.out.println(stu.name);//赵丽颖
		System.out.println(stu.age);//18
				
		System.out.println("===================================");

		//4.使用对象的成员方法
		//格式:对象名.成员方法名([参数])
		stu.eat();
		stu.sleep();
		stu.study();
	}	
}

四、一个标准的类通常要拥有下面四个组成部分:(这样标准的一个类也叫Java bean)

  1. 所有的成员变量都要使用private关键字修饰
  2. 为每一个成员变量编写一对getter setter方法
  3. 编写一个无参数的构造方法
  4. 编写一个全参数的构造方法
public class Student2 {
	private String name;//姓名
	private int age;//年龄
	
	public Student2() {
		super();
	}
	
	public Student2(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public int getAge() {
		return age;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
}

五、构造方法:专门用来创建对象的方法 当我们通过关键字new来创建对象时 其实就是在调用构造方法
格式:

public 类名称(参数类型 参数名称,……){
	方法体;
}

【注】:

  1. 构造方法的名称必须和所在的类名称完全一样 就连大小写也要一样
  2. 构造方法不要写返回值类型 连void都不要写
  3. 构造方法不能return一个具体的返回值
  4. 如果没有编写任何构造方法 那么编译器就会默认赠送一个构造方法 没有参数 方法体什么也不做 即:public ConstructorStudent() {}
  5. 一旦编写了至少一个构造方法 那么编译器将不再赠送
  6. 构造方法可以进行重载
  7. 全参和无参构造方法可以方便我们在创建对象时 把现成的数据通过参数的形式设置进来 省去多次调用setter getter方法的麻烦
  8. 当需要修改对象内容时 即重新传递数据时 还是需要用到setter getter方法
public class ConstructorStudent {
	//成员变量
	private String name;
	private int age;
	
	//无参数的构造方法
	public ConstructorStudent() {
		System.out.println("无参构造方法执行啦!");
	}
	//有参数的构造方法
	public ConstructorStudent(String name,int age) {
		System.out.println("有参构造方法执行啦!");
		this.setName(name);
		this.setAge(age);
	}
	//getter setter
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public int getAge() {
		return age;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
}

使用时:

public class ConstructorStudentUse {
	public static void main(String[] args) {
		ConstructorStudent stu = new ConstructorStudent();//无参构造方法
		ConstructorStudent stu2 = new ConstructorStudent("赵丽颖",20);//有参构造方法
		System.out.println("姓名:" + stu2.getName() + ",年龄:" + stu2.getAge());
		//如果需要改变对象当中的成员变量数据内容 仍然还需要使用setter方法
		stu2.setAge(21);
		System.out.println("姓名:" + stu2.getName() + ",年龄:" + stu2.getAge());
	}
}

封装

一、封装:将一些细节信息隐藏起来 对于外界不可见
二、封装的两种形式:

  1. 方法就是一种封装
  2. 关键字private也是一种封装

三、问题描述:定义Person的年龄时 无法阻止不合理的数值被设置进来 如:-20
四、解决方法:用private关键字将需要保护的成员变量进行修饰。
五、一旦使用了private进行修饰 那么本类当中仍然可以随意访问 但是 超出了本类范围就不能再直接访问了 可以间接访问。
六、间接访问private成员变量 就是定义一对getter/setter方法

【注】:

  1. setter方法必须含有形参 且形参的数据类型和要设置的成员变量的数据类型一致
  2. getter方法不能含有参数 返回值的数据类型和要获取的成员变量的数据类型一致
  3. 必须叫getXxx或者setXxx
  4. 对于基本数据类型当中的boolean值 getter方法一定要写成isXxx的形式 而setXxx规则不变
public class PrivatePerson {
	String name;
	private int age;
	public void show() {
		System.out.println("我叫:" + name + ",年龄:" + age);
	}
	
	//这个成员方法专门用于向age设置数据
	public void setAge(int num) {//该成员方法的名称必须以set开头 且后面紧跟首字母大写的成员变量
		if(num < 100 && num >=0) {
			age = num;
		}else {
			System.out.println("数据不合理!");
		}
	}
	
	//这个成员方法专门用于获取age的数据
	public int getAge() {//该成员方法的名称必须以get开头 且后面紧跟首字母大写的成员变量
		return age;
	}
}

七、当方法的局部变量和类的成员变量重名时 根据“就近原则” 优先使用局部变量,如果需要访问本类当中的成员变量 需要使用格式:this.成员变量名
八、“通过谁调用的方法 谁就是this”:stu调用的setName setAge setMale 所以stu就是this

public class PrivateStudent {
	private String name;
	private int age;
	private boolean male;//是不是男的
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	public boolean isMale() {
		return male;
	}
	public void setMale(boolean male) {
		this.male = male;
	}
}

使用时:

public class PrivateStudentUse {
	public static void main(String[] args) {
		PrivateStudent stu = new PrivateStudent();
		
		stu.setName("鹿晗");
		stu.setAge(20);
		stu.setMale(true);

		System.out.println("姓名:" + stu.getName());
		System.out.println("年龄:" + stu.getAge());
		System.out.println("是不是男:" + stu.isMale());
	}
}

匿名对象

一、创建对象的标准格式:类名称 对象名 = new 类名称();
二、匿名对象就是只有右边的对象 没有左边的“类名称 对象名 =
三、匿名对象的格式:new.类名称

【注】:匿名对象只能使用唯一的一次 下次再用就要再创建一个新对象

四、使用建议:如果确定有一个对象只需要使用唯一一次就可以使用匿名对象

import java.util.Scanner;
public class Anonymous {
	public static void main(String[] args) {
		//创建对象的标准格式
		AnonymousPerson one = new AnonymousPerson();//左边one就是对象的名字
		one.name = "高圆圆";
		one.showName();//我叫高圆圆
		
		System.out.println("匿名对象的使用:======================================");

		//匿名对象
		new AnonymousPerson().name = "赵又廷";
		new AnonymousPerson().showName();//我叫null
		/*为啥这里不输出“我叫赵又廷”:
		 * 在这个类里面有三个new 也就创建了三个不同的对象
		 * “赵又廷”是给第二个对象的name赋的值 而我们并没有给第三个对象的name赋值 所以 第三个对象打印null
		 */
		
		System.out.println("匿名对象在Scanner中的应用:======================================");

		//Scanner的普通使用方式
		Scanner sc1 = new Scanner(System.in);
		System.out.println("请输入第一个数字:");
		int num1 = sc1.nextInt();
		System.out.println("输入的第一个数字:" + num1);

		//Scanner的匿名对象使用方式
		System.out.println("请输入第二个数字:");
		int num2 = new Scanner(System.in).nextInt();
		System.out.println("输入的第二个数字:" + num2);

		System.out.println("匿名对象作为方法的参数:======================================");

		//使用一般写法传入参数
		System.out.println("请输入第三个数字:");
		Scanner sc2 = new Scanner(System.in);
		methodParam(sc2);
		
		//使用匿名对象来传参
		System.out.println("请输入第四个数字:");
		methodParam(new Scanner(System.in));
		
		System.out.println("匿名对象作为方法的返回值:======================================");

		Scanner sc3 = methodReturn();
		int num3 = sc3.nextInt();
		System.out.println("输入的第五个数字:" + num3);
	}

	private static Scanner methodReturn() {
		/*一般写法
		 * Scanner sc4 = new Scanner(System.in);
		 * return sc4;
		 */
		
		//匿名对象作为方法的返回值
		return new Scanner(System.in);
	}

	private static void methodParam(Scanner sc) {
		int num = sc.nextInt();
		System.out.println("输入的第三/四个数字:" + num);
	}
}

ArrayList

一、数组的长度不能发生改变 但是ArrayList集合的长度可以随意改变
二、对于ArrayList来说 有一个尖括号<E>代表泛型
三、泛型:装在集合当中的所有元素 全都是统一的什么类型

【注】:

  1. 泛型只能是引用类型 不能是基本类型
  2. 对于ArrayList集合来说 直接打印得到的不是地址值 而是内容 如果内容是空 得到的是空的中括号:[]

四、如果希望向集合ArrayList当中存储基本类型数据 必须使用基本类型对应的“包装类”

基本类型包装类
byteByte
shortShort
intInteger
longLong
floatFloat
charCharacter
booleanBoolean

五、从JDK1.5+开始 支持自动装箱 自动拆箱

  1. 自动装箱:基本类型自动转换为包装类型
  2. 自动拆箱:包装类型自动转换为基本类型
import java.util.ArrayList;
public class ArrayListBasic {
	public static void main(String[] args) {
		//正常情况下创建一个ArrayList集合 集合的名称是listA 里面装的全是String字符串类型的数据 只能装引用类型的数据
		ArrayList<String> listA = new ArrayList<>();
		//ArrayList<int> listB = new ArrayList<>();错误!泛型只能是引用类型 不能是基本类型
		
		//使用包装类定义了一个ArrayList集合 集合的名称是listC 里面装的全是int类型的数据
		ArrayList<Integer> listC = new ArrayList<>();
		listC.add(100);
		listC.add(200);
		System.out.println(listC);//[100, 200]

		//获取包装类数据
		int num = listC.get(1);
		System.out.println("第一号元素是:" + num);//200
	}
}

六、ArrayList常用方法:

  1. public boolean add(E e):向集合中添加元素 参数类型和泛型一致 返回值代表添加是否成功

【注】:对于ArrayList集合来说 add添加动作一定是成功的 所以返回值可用可不用,但是对于其他集合(今后学习)来说 add添加动作不一定成功

  1. public E get(int index):从集合中获取元素 参数是索引编号 返回值就是对应位置的元素 E是泛型
  2. public E remove(int index):从集合中删除元素 参数是索引编号 返回值就是被删除的元素
  3. public int size():获取集合的尺寸长度 返回值是集合中包含的元素个数

Scanner类

一、Scanner类的功能:可以实现键盘输入数据到程序中
二、引用类型的一般步骤:

  1. 导包:import 包路径.类名称

【注】:

  1. 如果需要使用的目标类和当前类位于同一个包下 则可以省略导包语句不写
  2. 只有Java.lang包下的内容不需要导包 其他的包都需要import语句
  1. 创建:类名称 对象名 = new 类名称([参数]);
  2. 使用:对象名.成员方法名([参数]);

三、获取键盘输入的一个int数字:int num = sc.nextInt();
四、获取键盘输入的一个字符串:String str = sc.next();
五、其实键盘输入的全都是字符串 而nextInt把字符串化成了int数字展示出来 而next则是直接把键盘上输入的字符串拿过来直接显示

import java.util.Scanner;//1.导包
public class ScannerClass {
	public static void main(String[] args) {
		//2.创建
		Scanner sc = new Scanner(System.in);//System.in表示从键盘输入
		//3.使用
		int num = sc.nextInt();//获取键盘输入的一个int数字
		System.out.println("输入的int数字是:" + num);
		
		System.out.println("==================================================");
		String str = sc.next();//获取键盘输入的一个字符串
		System.out.println("输入的字符串是:" + str);
	}
}

Random类

Random类用来生成随机数字 使用起来也是三个步骤:

  1. 导包:import java.util.Random;
  2. 创建:Random r = new Random();//小括号中留空即可
  3. 使用:
    (1)获取一个随机的int数字(范围是int所有范围 由正负两种):int num = r.nextInt();
    (2)获取一个随机的int数字(参数代表了范围 左闭右开区间):int num = r.nextInt(3);实际上代表的含义是[0,3) 也就是0-2
import java.util.Random;
public class RandomClass {
	public static void main(String[] args) {
		Random r1 = new Random();
		int num1 = r1.nextInt();
		System.out.println("随机数是:" + num1);//-1565682014     1106506546
		
		Random r2 = new Random();
		for(int i = 0;i < 100;i++) {
			int num2 = r2.nextInt(10);//生成0-9的随机整数
			System.out.println("随机数是:" + num2);
		}
	}
}

String类

一、java.lang.String类代表字符串
二、API当中说 Java程序中的所有字符串字面值(如“abc”)都作为此类的实例实现,其实就是说,程序当中所有的双引号字符串都是String类的对象 就算没有new 也照样是
三、字符串的特点:

  1. 字符串的内容永不可变
  2. 正是因为字符串不可改变 所以字符串是可以共享使用的
  3. 字符串效果上相当于是char[]字符数组 但是底层原理是byte[]字节数组
  4. 创建字符串的常见3+种方式:
    (1)三种构造方法:(new就是在调用构造方法)
    public String():创建一个空白字符串 不含有任何内容
    public String(char[] array):根据字符数组的内容来创建对应的字符串
    public String(byte[] array):根据字节数组的内容来创建对应的字符串
    (2)一种直接创建:String str = "Hello";//右边直接用双引号

【注】:直接写上双引号 就是字符串对象

public class StringClass {
	public static void main(String[] args) {
		//使用空参构造
		String str1 = new String();//小括号留空说明字符串什么内容都没有
		System.out.println("第一个字符串:" + str1);//第一个字符串:
		
		//根据字符数组的内容来创建对应的字符串
		char[] charArray = {'a','b','c'};
		String str2 = new String(charArray);
		System.out.println("第二个字符串:" + str2);//第二个字符串:abc

		//根据字节数组的内容来创建对应的字符串
		byte[] byteArray = {97,98,99};
		String str3 = new String(byteArray);
		System.out.println("第三个字符串:" + str3);//第三个字符串:abc
		
		//直接创建
		String str4 = "Hello";
		System.out.println("第四个字符串:" + str4);//第四个字符串:Hello
	}
}

字符串转换

String当中与转换相关的常用方法有:

  1. public char[] toCharArray():将当前字符串拆分成为字符数组作为返回值
  2. public byte[] getBytes():获得当前字符串底层的字节数组
  3. public String replace(CharSequence oldString,CharSequence newString):将所有出现的老字符串替换成新的字符串 返回替换后的结果新字符串
  4. CharSequence:接口 可以接收字符串类型
public class StringConvert {
	public static void main(String[] args) {
		//转换成为字符数组
		char[] chars = "Hello".toCharArray();
		System.out.println(chars[0]);//H
		System.out.println(chars.length);//5
		
		System.out.println("=================================================");
		
		//转换成为字节数组
		byte[] bytes = "abc".getBytes();
		for(int i = 0;i < bytes.length;i++) {
			System.out.println(bytes[i]);//97 98 99
		}
		
		System.out.println("==================================================");
		
		//
		String str1 = "How do you do?";
		String str2 = str1.replace("o", "*");
		System.out.println(str1);//How do you do?
		System.out.println(str2);//H*w d* y*u d*?
	}
}

字符串获取

String中与获取相关的常用方法:

  1. public int length():获取字符串当中含有的字符个数 拿到字符串长度
  2. public String cancat(String str):将当前字符串和参数字符串拼接成为返回值新的字符串
  3. public char charAt(int index):获取指定索引位置的单个字符 索引从0开始
  4. public int indexOf(String str):查找参数字符串在本字符串当中首次出现的索引位置 如果没有 返回-1值
public class StringGet {
	public static void main(String[] args) {
		//获取字符串的长度
		System.out.println("获取字符串长度:======================================");
		int length = "asdfghjkloivf".length();
		System.out.println("字符串的长度是:" + length);//字符串的长度是:13
		
		//拼接字符串
		System.out.println("拼接字符串:====================================");
		String str1 = "Hello";
		String str2 = "World";
		String str3 = str1.concat(str2);
		System.out.println(str1);//Hello
		System.out.println(str2);//World
		System.out.println(str3);//HelloWorld

		//获取指定索引位置的单个字符
		System.out.println("获取指定索引位置的单个字符:=====================================");
		char ch = "Hello".charAt(1);
		System.out.println("在1号索引位置的字符是:" + ch);//在1号索引位置的字符是:e
		
		//查找参数字符串在本来字符串当中出现的第一次索引位置 如果根本没有 返回-1
		String original = "HelloWorldHelloWorld";
		int index = original.indexOf("llo");
		System.out.println("第一次索引值是:" + index);//第一次索引值是:2
		System.out.println("HelloWorld".indexOf("abc"));//-1
	}
}

字符串分割

分割字符串的方法:public String[] split(String regex):按照参数的规则将字符串切分成若干部分并保存在String数组中

注意事项:split方法的参数其实是一个正则表达式 所以如果按照英文句点“.”切分必须写“\\.

public class StringSplit {
	public static void main(String[] args) {
		String str1 = "aaa,bbb,ccc";
		String[] array1 = str1.split(",");
		for(int i = 0;i < array1.length;i++) {
			System.out.println(array1[i]);
		}
		System.out.println("==================================================");

		//按照“.”进行切割 会报错
		String str2 = "aaa.bbb.ccc";
		String[] array2 = str1.split(".");
		for(int i = 0;i < array1.length;i++) {
			System.out.println(array2[i]);
		}
	}
}

字符串截取

字符串的截取方法:

  1. public String substring(int index):截取从参数位置一直到字符串末尾 返回新字符串
  2. public String substring(int begin,int end):截取从begin开始 一直到end结束 中间的字符串

备注:[begin,end) 包含左边 不包含右边

public class Substring {
	public static void main(String[] args) {
		String str1 = "HelloWorld";
		String str2 = str1.substring(5);
		System.out.println(str1);//HelloWorld
		System.out.println(str2);//World

		System.out.println("===================");

		String strA = "Hello";
		System.out.println(strA);//Hello
		strA = "Java";
		System.out.println(strA);//Java
/*
 * 不是说字符串中保存的内容不变吗?为什么这里变了:
 * 注意 上面这种写法 字符串的内容仍然是没有改变的
 * 上面有;两个字符串:"Hello" "Java"
 * strA中保存的是地址值 本来地址值是Hello的0x666 后来地址值变成了Java的0x999
 */
	}
}

字符串常量池

一、字符串常量池:程序当中直接写上的双引号字符串就在字符串常量池中 new的不在池中
二、==

  1. 对于基本类型来说 ==是进行数值的比较
  2. 对于引用类型来说 ==是进行【地址值】的比较
public class ArrayPool {
	public static void main(String[] args) {
		String str1 = "abc";
		String str2 = "abc";
		char[] charArray = {'a','b','c'};
		String str3 = new String(charArray);
		System.out.println(str1 == str2);//true
		System.out.println(str1 == str3);//false
		System.out.println(str3 == str2);//false
	}
}

三、分析:

  1. str1 str2:程序会用底层的byte数组来表示字符串“abc” 假设表示字符串“abc”的底层byte数组的地址值为0x333,在堆中有一个字符串常量池 程序当中直接写上的双引号字符串就在字符串常量池中 ,所以该常量池存放字符串对象“abc”所在的byte数组的地址值0x333,在栈中str1和str2保存的都是字符串常量池中保存0x333的地址值 假设是0x666
  2. str3:定义了一个字符数组(在堆中)假设该字符数组在堆中的地址为0x999 charArray保存的就是0x999,当new String(charArray)时 程序会先把字符数组转换成底层byte数组{"97","98","99"} ,假设该byte数组的地址值为0x111 再new上一个字符串对象 该对象保存0x111 假设字符串对象所在地址为0x222,在栈中str3保存的就是0x222

四、==是进行对象的地址值比较 如果确实需要字符串的内容比较 可以使用以下两个方法:

  1. public boolean equals(Object obj):参数可以是任何对象
    只有参数是一个字符串并且内容相同的才会给true 否则返回false

【注】:

  1. 任何对象都能用Object进行接收
  2. equals方法具有对称性 也就是a.equals(b)和b.equals(a)效果一样
  3. 如果比较双方一个常量一个变量推荐把常量字符串写在前面 推荐:"abc".equals(str1) 不推荐:str1.equals(“abc”),因为可能出现空指针异常
  1. public boolean equalsIgnoreCase(String str):忽略大小写进行内容的比较
public class ArrayEquals {
	public static void main(String[] args) {
		System.out.println("不区分大小写比较");
		String str1 = "abc";
		String str2 = "abc";
		char[] charArray = {'a','b','c'};
		String str3 = new String(charArray);
		System.out.println(str1.equals(str2));//true
		System.out.println(str1.equals(str3));//true
		System.out.println(str3.equals(str2));//true
		System.out.println("abc".equals(str1));//true
		System.out.println("ABC".equals(str2));//false

		System.out.println("为什么常量不能写在后面:");
		String str4 = null;
		System.out.println("abc".equals(str4));//推荐 false
		//System.out.println(str4.equals("abc"));//不推荐 会报错:空指针异常

		System.out.println("区分大小写比较");
		String strA = "JAVA";
		String strB = "java";
		System.out.println(strA.equals(strB));//false 严格区分大小写
		System.out.println(strA.equalsIgnoreCase(strB));//true 忽略大小写

		//注意:只有英文字母区分大小写 其他都不区分大小写
		System.out.println("一".equalsIgnoreCase("壹"));//false
	}
}

Math类

java.util.Math是数学相关的工具类 里面提供了大量的静态方法 完成与数学运算相关的操作

  1. public static double abs(double num):获取绝对值
  2. public static double ceil(double num):向上取整
  3. public static double floor(double num):向下取整
  4. public static long round(double num):四舍五入
  5. Math.PI代表近似的圆周率常量(double)

静态代码块

一、定义一个学生类 包含:姓名 年龄 学号 所在教室。以此产生了三个学生对象 拥有不同的姓名 年龄 学号 但是他们是同班同学 所以所在教室一样 这应该是多个对象共享同一份数据,如果给每个学生对象都设置所在教室为101 那么如果我要他们全部换到103教室 就需要对每个对象单独更改 要更改三次,如果我们在类中使用static关键字 就可以只在学生类中保存一份所在教室 所有本类对象共享这一份,一旦用了static关键字 那么这样的内容不再属于对象自己 而是属于类的 所以所有本类对象共享这一份

public class Student {
	private String name;
	private int age;
	static String room;// 存放在方法区的静态区,仅此一份,全类对象共享这一份
	private int id;
	private static int idCounter = 0;//学号计数器 每当new了一个新对象 计数器+1
	
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
		this.setId(++idCounter);
	}
	public Student() {
		super();
		this.setId(++idCounter);
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
}

二、内存中:在方法区中有个静态区 用来存放static关键字定义的数据,当编译器看到oneStudent.room就会去方法区中找static String room变量 该变量中存储的是静态区中"101教室"存储的地址值

【注】:根据类名称访问静态成员变量时 全程和对象没关系 只和类有关系

import javax.sound.midi.Soundbank;
public class StaticClass {
	public static void main(String[] args) {
		Student oneStudent = new Student("郭靖",19);
		oneStudent.room = "101教室";
		System.out.println("姓名:" + oneStudent.getName() + ",年龄:" + oneStudent.getAge()
							+ ",所在教室:" + oneStudent.room + ",学号:" + oneStudent.getId());
		//姓名:郭靖,年龄:19,所在教室:101教室,学号:1

		Student twoStudent = new Student("黄蓉",16);
		System.out.println("姓名:" + twoStudent.getName() + ",年龄:" + twoStudent.getAge()
							+ ",所在教室:" + oneStudent.room + ",学号:" + twoStudent.getId());
		//姓名:黄蓉,年龄:16,所在教室:101教室,学号:2
	}
}

三、一旦使用static修饰成员方法 那么这就成为了静态方法 静态方法不属于对象 而是属于类,如果没有static关键字 那么必须先创建对象 然后通过对象才能使用他,如果有了static关键字 那么不需要创建对象 直接就能通过类名称来使用他,无论是成员变量 还是成员方法 如果有了static 都推荐使用类名称进行调用
四、静态变量:类名称.静态变量
五、静态方法:类名称.静态方法([参数])

【注】:

  1. 静态只能直接访问静态 不能直接访问非静态 因为在内存中是先有的静态内容 后有的非静态内容。“先人不知道后人 但是后人知道先人”
  2. 静态方法中不能用this 因为this代表当前对象 通过谁调用的方法 谁就是当前对象 而静态跟对象无关
public class StaticMethod {
	public static void main(String[] args) {
		MyClass objClass = new MyClass();//首先创建对象
		objClass.method();//然后才能使用没有static关键字的内容
		
		//对于静态方法来说 可以通过对象名进行调用 也可以直接通过类名称来调用
		objClass.methodStatic();//正确 但是不推荐 因为这可能会让人误以为是对象的成员方法
		MyClass.methodStatic();//正确 推荐
		
		//对于本类当中的静态方法 可以省略类名称
		myMethod();
		StaticMethod.myMethod();//两者完全等效
	}

	private static void myMethod() {
		System.out.println("自己的方法!");
	}
}

六、直接用一个{}包起来的都叫代码块
七、静态代码块的格式:

public class 类名称{
 		static{
 			//静态代码块的内容
 		}
}

八、特点:当第一次用到本类时 静态代码块执行唯一的一次 如果再用到本类 静态代码块就不执行了
九、静态内容总是优先于非静态 所以静态代码块比构造方法先执行
十、静态代码块的典型用途:用来一次性地对静态成员变量进行赋值

public class Static {
	public static void main(String[] args) {
		Person onePerson = new Person();//静态方法先执行
		Person twoPerson = new Person();//静态方法不执行 只执行构造方法
	}
}

Person类:

public class Person {
	static {
		System.out.println("静态代码块执行了!");
	}
	public Person(){
		System.out.println("构造方法执行!");
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值