目录
StringBuffer 和 StringBuilder 区别
一、什么是方法?
方法是程序中最小的执行单元
优点:1.提高代码的复用性 2.提高代码的可维护性
1.方法的格式
最简单的方法的定义和调用
定义格式:
public static void 方法名(){
方法体(就是打包起来的代码);
}
调用格式:
方法名();
带参数的方法的定义和调用
定义格式:
public static void 方法名(参数1,参数2,…){ //括号内参数称为行参
方法体(就是打包起来的代码);
}
调用格式:
方法名(参数1,参数2,…); //括号内参数称为实参
注意:形参和实参需要一一对应
带返回值的方法的定义和调用
使用场景:在调用处需要根据方法的结果,去编写另一段代码
定义格式:
public static 返回值类型 方法名(参数1,参数2,…){
方法体(就是打包起来的代码);
return 返回值;
}
调用格式:
直接调用:方法名(参数1,参数2,…); //一般用在无返回值的调用
赋值调用:数据类型 变量名 = 方法名(参数1,参数2,…);
输出调用:system.out.println(方法名(参数1,参数2,…));
2.方法的重载
定义:在同一个类中,方法名相同,参数不同(个数不同、类型不同、顺序不同)的方法,就是重载。与返回值无关。
//方法的重载
public class MethodDome1 {
/*需求:使用方法重载的思想,设计比较两个数是否相同的方法
要求:兼容全整数类型(byte,short,int,long)*/
public static void main(String[] args) {
//调用
compare(10,20);
//compare((byte)20,(byte)30);
}
public static void compare(byte b1,byte b2){
System.out.println("===byte===");
System.out.println(b1==b2);
}
public static void compare(short s1,short s2){
System.out.println("===short===");
System.out.println(s1==s2);
}
public static void compare(int i1,int i2){
System.out.println("===int===");
System.out.println(i1==i2);
}
public static void compare(long l1,long l2){
System.out.println("===long===");
System.out.println(l1==l2);
}
}
3.关于方法的两个练习
public class Exercise1 {
public static void main(String[] args) {
int[] arr1={11,22,33,44,55};
//printArr(arr1);
int[] arr2={1,45,7,10,3,6,8};
//调用方法求最大值
int max=getMax(arr2);
System.out.println(max);
}
public static void printArr(int[] arr1){
//需求:设计一个方法用于数组遍历,要求遍历的数组在一行上,例如:[11,22,33,44,55]
System.out.print("[");
for (int i = 0; i < arr1.length; i++) {
if(i== arr1.length-1){
System.out.print(arr1[i]);
}else {
System.out.print(arr1[i]+",");
}
}
System.out.println("]");
}
public static int getMax(int[] arr2){
//设计一个方法求数组的最大值,并将最大值返回
int max=arr2[0];
for (int i = 0; i < arr2.length; i++) {
if (arr2[i]>max){
max=arr2[i];
}
}
return max;
}
}
补充:return和break关键字的区别
return:和循环无关,和方法有关,表示1结束方法 2返回结果
如果方法执行到return,那么整个方法全部结束,里面的循环也随之结束
break:和方法无关,主要作用是结束循环或switch的
4.方法的内存
方法调用的基本内存原理
传递基本数据类型时,传递的是真实的数据,形参的改变,不影响实际参数的值
传递引用数据类型时,传递的是地址值,形参的改变,影响实际参数的值
方法传递基本数据类型的内存原理
基本数据类型:数据值是存储在自己的空间中
方法传递引用数据类型的内存原理
引用数据类型:使用了其他空间中(堆)的数据,变量中存储的是地址值
5.ststic 关键字
二、面向对象基础
1.类与对象
类(设计图):是对象共同特征的描述 对象:是真实存在的具体东西
在java中,必须先设计类,才能获得对象
如何定义类
public class 类名{
1.成员变量(代表属性,一般是名词)
2.成员方法(代表行为,一般是动词)
3.构造器
4.代码块
5.内部类
}
如何得到类的对象
类名 对象名 = new 类名();
如何使用对象
访问属性:对象名.成员变量;
访问行为:对象名.方法名(...);
定义类的补充注意事项
用来描述一类事物的类,专业叫做:Javabean类
在Javabean类中,是不写main方法的
编写main方法的类,叫做测试类
我们可以在测试类中创建Javabean类的对象并进行赋值调用
成员变量的完整定义格式是:
修饰符 数据类型 变量名称 = 初始化值;(一般无需指定初始化值,存在默认值)
2.构造方法
构造方法也叫构造器或构造函数。
作用:在创建对象的时候给成员变量进行初始化(赋值)的
构造方法的格式
public class Student{
修饰符 类名(参数) {
方法体;
}
}
特点:
方法名与类名相同,大小写也要一致
没有返回值类型,连void都没有
没有具体的返回值(不能有return带回结果数据)
构造方法的注意事项
构造方法的定义:
如果没有定义构造方法,系统将给出一个默认的无参数构造方法
如果定义了构造方法,系统将不在提供默认的构造方法
构造方法的重载:
带参构造方法和无参构造方法,两者方法名相同,但是参数不同,这叫做构造方法的重载
推荐使用方式:
无论是否使用,都要手动书写无参数构造方法和带全部参数的构造方法
3.标准的JavaBean类
类名需要见名知意
成员变量使用private修饰
提供至少两种构造方法
无参构造方法
带全部参数的构造方法
成员方法
提供每一个成员变量对应的setXxx()和getXxx()
如果还有其他行为,也需要写上
4.对象内存图
一个对象的内存图
Student s = new Student ( );
加载class文件
声明局部变量
在堆内存中开辟一个新空间
默认初始化
显示初始化
构造方法初始化
将堆内存中的地址值赋值给左边的局部变量
两个对象的内存图
注意:第二次在创建一个新对象的时候,不需要在方法区中加载一次字节码文件
5.封装
对象代表什么,就得封装对应的数据,并提供数据对应的行为
需要什么对象的时候,可查API帮助文档
private关键字
是一个权限修饰符
可以修饰成员(成员变量和成员方法)
被private修饰的成员只能在本类中才能访问
get和set方法
快捷键:alt+insert
set方法:给成员变量赋值
get方法:对外提供成员变量的值
6.继承(extends)
作用:提高代码的复用性,简化代码
继承的构造顺序
在实例化子类时,先执行父类构造方法,再执行子类构造方法;调用时,默认先调用父类无参构造方法
注意:父类构造方法定义问题,一般需要留上一个无参构造方法。
如果父类中只有有参构造,没有无参构造时,子类在构造方法中先去调用父类的构造方法
补充:父类和子类的执行顺序:
父类static --- 子类static --- 父类属性和父类代码段 --- 父类构造方法 --- 子类属性和子类代码段 --- 子类构造方法
7.重写
多态:
静态多态 ---- 重载 ---- 一个类中同名不同参
动态多态 ---- 重写 ---- 父子类中同名同参
多态的三个必备条件:1.继承 2.重写 3.父类指向子类对象的引用
软件设计原则:
OPC:开闭原则 ---- 对修改关闭对扩展开放
软件开发生命周期:
可行性分析 --- 需求分析 --- 概要设计 --- 详细设计 --- 开发 --- 测试 --- 维护
重写定义:子类中方法和父类中方法出现同名同参,称之为重写
@Override注解:用来检查是否符合重写规则
两大一小原则:
一大:子类重写方法访问权限大于或等于父类方法
一小:子类重写方法返回值类型小于或等于父类方法(可以自动向上转型),不包括基本类型
一小:子类方法抛出异常类型小于或等于父类方法抛出异常类型
instance of :运算符,判断实例是否属于指定类型;在判断时,把大类放在后面
8.super关键字
用法:
调用父类构造方法:super.([参数列表]); ------------只能用在构造方法第一句
调用父类普通成员(属性、方法、内部类):super.propName;super.methodName(); ------------可以用在构造方法也可用在普通方法,位置顺序没有限制
9.就近原则和this关键字
就近原则
System.out.println(age) 先到局部变量位置找值,如果没有,再到成员变量位置找值
System.out.println(this.age) 直接到成员变量位置找值
this关键字的作用
可以区别成员变量和局部变量
this关键字的本质
所在方法调用者的地址值
10.final 关键字(最终)
修饰类:类不能被继承
修饰方法:方法不能被重写
修饰变量:变量变成常量,不能多次被修改赋值(常量命名全部大写,多个单词组合时,用下划线分开)。修饰的属性,在声明时,必须要初始化
扩展:
finalize() 是属于 Object 类中的方法
作用:在垃圾回收器回收对象时,回去调用执行的方法。
11.访问权限
访问修饰符 | 内部类 | 同包下的类 | 不同包下的类 | 其他包的类 |
---|---|---|---|---|
private | 可以访问 | 不可以 | 不可以 | 不可以 |
默认的(同包) | 可以 | 可以 | 不可以 | 不可以 |
protected | 可以 | 可以 | 可以 | 不可以 |
public | 可以 | 可以 | 可以 | 可以 |
12.克隆
克隆方法:
重写 Object clone() 方法 ------ 可以把访问修饰权限改成 public
@Override public Object clone() throws CloneNotSupportedException { return super.clone();
实现可克隆的接口 ------- implements Cloneable
浅克隆和深克隆:
浅克隆:只克隆基本类型或 String 属性,对于依赖的引用类型对象,只克隆了地址。
深克隆:依赖的引用类型对象,也会进行克隆
13.抽象类(abstract)
abstract关键字修饰的类,称之为抽象类;
abstract修饰的方法,称之为抽象方法,抽象方法不能有方法体;
拥有抽象方法的类,必须定义为抽象类,但抽象类中不一定有抽象方法;
抽象类不能被实例化;
子类继承抽象类时,要么实现抽象类中所有的抽象方法,要么把子类声明为抽象类;
抽象类和普通类的区别:
抽象类中可以有抽象方法,普通类不可以
抽象类不能被实例化
14.接口
接口特点(多实现、多个功能):
定义:interface
属性:默认是且只能是 public static final 的常量
方法:默认是且只能是 public abstract,可以省略
构造:接口没有且不能定义构造方法
内部类:默认是 public static 的内部类
代码段:接口中不能使用代码段
解耦
/*
* 接口:规范、功能、标准
* */
public class TestInterface {
public static void main(String[] args) {
HuaWeiPhone phone=new HuaWeiPhone();
IPlayer player=phone; //手机是一个播放器
phone.net();
phone.play();
phone.sendSMS();
phone.takePhoto();
phone.call();
}
}
/*生产一个华为手机*/
class HuaWeiPhone extends Phone implements ICamera,IPlayer,INet{
@Override
public void sendSMS() {
System.out.println("=====发短信=====");
}
@Override
public void takePhoto() {
System.out.println("=====拍照片=====");
}
@Override
public void play() {
System.out.println("=====放音乐======");
}
@Override
public void net() {
System.out.println("======上网======");
}
}
abstract class Phone{
public abstract void sendSMS();
public void call(){
System.out.println("=====打电话=====");
}
}
/*相机接口*/
interface ICamera{
void takePhoto();
}
/*播放器接口*/
interface IPlayer{
void play();
}
/*网络接口*/
interface INet{
void net();
}
三、字符串
创建String对象的两种方式
直接赋值
使用new关键字来获取字符串对象
字符串常用的一些方法
public class TestString {
public static void main(String[] args) {
String srt = "yay.123.zbx ";
System.out.println("length():"+srt.length()); //长度
System.out.println(srt.contains("zb")); //是否包含
System.out.println(srt.concat("xyz")); //拼接
System.out.println(srt.replaceAll("3","5")); //替换
System.out.println(srt.indexOf(".")); //查找第一个字符 . 所在的位置
System.out.println(srt.lastIndexOf(".")); //从后面查找最后一个字符 . 所在的位置
System.out.println(srt.charAt(2)); //给定下标找字符
System.out.println(srt.substring(4,7)); //截取子串,注意,不包含后面位置的字符
System.out.println(srt.substring(srt.indexOf(".")+1,srt.lastIndexOf(".")));
System.out.println(srt.toLowerCase()); //全部转换为小写字母
System.out.println(srt.toUpperCase()); //全部转换为大写字母
System.out.println(srt.endsWith(".java")); //是否以指定字符串结尾
System.out.println(srt.startsWith("ya")); //是否以指定字符串开头
System.out.println("==="+srt.trim()+"==="); //去空格
}
}
字符串的比较
public class StringCompare {
public static void main(String[] args) {
//1.创建两个字符串对象
String s1=new String("abc"); //记录的是堆中的地址
String s2="abc"; //直接赋值,记录的是串池中的地址
//2.==号比较
//基本数据类型:比的是数据值
//引用数据类型:比的是地址值
System.out.println(s1==s2);
System.out.println("======");
//3.比较字符串中对象的内容是否相等,完全一样 boolean equals
boolean result1 = s1.equals(s2);
System.out.println(result1);
System.out.println("======");
//4.比较字符串中对象的内容是否相等,忽略大小写 boolean equalsIgnoreCase
boolean result2 = s1.equalsIgnoreCase(s2);
System.out.println(result2);
}
}
StringBuffer 和 StringBuilder 区别
StringBuffer 方法都是有 synchronized 关键字修饰的
StringBuffer 线程同步的,安全的,效率低,推荐多线程场景使用
StringBuilder 非线程同步的,不安全的,相对效率高,推荐多线程场景下使用
正则表达式
作用:
校验字符串是否满足一定的规则
在一段文本中查找想要的内容
练习1--模拟用户登录
/*已知正确的用户名和密码,请用程序模拟实现用户登录
* 一共三次机会,登录之后,给出相应的提示*/
public class Exercise1 {
public static void main(String[] args) {
//定义两个变量记录正确的用户名和密码
String rightUsername = "zhangsan";
String rightPassword = "123456";
//键盘录入用户名和密码
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < 3; i++) {
System.out.println("请输入用户名:");
String username = scanner.next();
System.out.println("请输入密码:");
String password = scanner.next();
//比较
if (username.equals(rightUsername) && password.equals(rightPassword)) {
System.out.println("用户登录成功!");
break;
} else {
if (i == 2) {
//最后一次机会也登录错误,此时要提示账户被锁定
System.out.println("三次机会登录失败,账号" + username + "被锁定!");
} else {
System.out.println("用户登录失败,用户名或密码错误,您还有" + (2 - i) + "次机会!");
}
}
}
}
}
练习2--遍历字符串和统计字符次数
public char charAt(int index) 根据索引返回字符
public int length( ) 返回此字符串的长度
数组的长度:数组名.length
字符串的长度:字符串对象.length( )
public class Exercise2 {
public static void main(String[] args) {
// Test1();
Test2();
}
public static void Test1() {
/*字符串遍历
* 需求:键盘录入一个字符串,使用程序实现在控制台遍历该字符串
*/
//键盘录入一个字符串
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个字符串:");
String str = scanner.next();
//进行遍历
for (int i = 0; i < str.length(); i++) {
//i依次表示字符串中的每个索引
char c = str.charAt(i);
System.out.print(c + " ");
}
}
public static void Test2(){
/*统计字符次数
* 键盘录入一个字符串,统计该字符串中大写字母字符,
* 小写字母字符,数字字符出现的次数(不考虑其他字符)
*/
//1.键盘录入一个字符串
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个字符串:");
String str = scanner.next();
//2.统计---计数器思想++
//定义三个计数器
int bigCount=0;
int smallCount=0;
int numberCount=0;
//3.进行遍历
for (int i = 0; i < str.length(); i++) {
//i一次表示字符串中的每个索引
char c = str.charAt(i);
if (c>='A'&&c<='Z'){
bigCount++;
}else if (c>='a'&&c<='z'){
smallCount++;
}else if (c>='0'&&c<='9'){
numberCount++;
}
}
//4.打印
System.out.println("大写字母有"+bigCount+"个!");
System.out.println("小写字母有"+smallCount+"个!");
System.out.println("数字字符有"+numberCount+"个!");
}
}
四、常用类
1.常用的数学类
public class TestMath {
public static void main(String[] args) {
System.out.println(Math.PI);
System.out.println(Math.max(66,77)); //求两位数的最大值
System.out.println(Math.min(45,67)); //求两位数的最小值
System.out.println(Math.abs(-9)); //求绝对值
System.out.println(Math.random()); //随机数,范围 [0,1)
System.out.println(Math.pow(2,3)); //次方,2的3 次方
System.out.println(Math.ceil(1.2)); //向上取整, ceil:天花板
System.out.println(Math.floor(2.9)); //向下取整, floor:地板
System.out.println(Math.round(1.6)); //四舍五入
}
}
2.包装类
包装类:基本数据类型对应的引用数据类型
/*
*两种方式获取Integer对象的区别
* */
public class TestInteger {
public static void main(String[] args) {
//底层原理:
//因为在实际开发中,-128~127之间的数据用的比较多
//如果每次使用数据都是new一个新的对象,太浪费内存
//所以,提前把这个范围中的每个对象创建好内存
//如果要用到了不会创建新的,而是返回已经创建好的对象
Integer i1 = Integer.valueOf(127);
Integer i2 = Integer.valueOf(127);
System.out.println(i1 == i2); //true
Integer i3 = Integer.valueOf(128);
Integer i4 = Integer.valueOf(128);
System.out.println(i3 == i4); //false
//因为有new关键字,在java中,每一次new都是创建了一个新的对象
//所以下面两个对象都是new出来的,地址不一样
Integer i5 = new Integer("127");
Integer i6 = new Integer("127");
System.out.println(i5 == i6); //false
Integer i7 = new Integer("128");
Integer i8 = new Integer("128");
System.out.println(i7 == i8); //false
}
}
自动装箱:把基本数据类型自动变成其对应的包装类。
自动拆箱:把包装类自动变成其对应的基本数据类型。
注意:在 JDK5 以后,int 和 Integer 可以看做是同一个东西,因为他们在内部可以自动转化。
如何获取包装类对象? 不需要 new,不需要调用方法,直接赋值即可。