文章目录
- 一、数组(Array)
- 二、数组的内存分析
- 三、Array工具类
- 四、面向对象的一些小知识
- 五、进阶知识补充
- 1. this关键字
- 2.继承
- 3.方法重写
- 4.super关键字的使用
- 5.子类对象实例化
- 6.多态性的体现
- 7.向下转型
- 8.Object类
一、数组(Array)
数组:多个相同类型数据按照一定顺序排列的集合,用一个名字命名,通过编号的方式进行统一的管理
Java中的容器:数组、集合框架:在内存中对多个数据的存储
//三种定义方式
int[] arr1=new int[5];
int[] arr2=new int[]{1,2,3};
int[] arr3={1,2,3};
// 二维数组的初始化
int[][] a1= new int[][]{{1},{2}};
// 静态初始化 new 中[][]不可以写数字
int[][] a11= new int[][]{{1},{2}};
int a22[][]=new int[2][];
int[][] a3=new int[2][4];
int[][] a4=new int[2][];
数组下标之所以要从0开始编号,因为这代表的是个偏移量,第一个元素与首地址一样,所以偏移量就是0,数组只有length属性,String有length()方法
二、数组的内存分析
区域名称 | 作用 |
---|---|
虚拟机栈 | 用于存储正在执行的每个Java方法的局部变量表等。局部变量表存放了编译期可知长度 的各种基本数据类型、对象引用,方法执行完,自动释放。 |
堆内存 | 存储对象(包括数组对象),new来创建的,都存储在堆内存。 |
方法区 | 存储已被虚拟机加载的类信息、常量、(静态变量)、即时编译器编译后的代码等数据。 |
本地方法栈 | 当程序中调用了native的本地方法时,本地方法执行期间的内存区域 |
程序计数器 | 程序计数器是CPU中的寄存器,它包含每一个线程下一条要执行的指令的地址 |
三、Array工具类
数组元素拼接
- static String toString(int[] a) :字符串表示形式由数组的元素列表组成,括在方括号(“[]”)中。相邻元素用字符 ", "(逗号加空格)分隔。形式为:[元素1,元素2,元素3。。。]
- static String toString(Object[] a) :字符串表示形式由数组的元素列表组成,括在方括号(“[]”)中。相邻元素用字符 ", "(逗号加空格)分隔。元素将自动调用自己从Object继承的toString方法将对象转为字符串进行拼接,如果没有重写,则返回类型@hash值,如果重写则按重写返回的字符串进行拼接。
数组排序
- static void sort(int[] a) :将a数组按照从小到大进行排序
- static void sort(int[] a, int fromIndex, int toIndex) :将a数组的[fromIndex, toIndex)部分按照升序排列
- static void sort(Object[] a) :根据元素的自然顺序对指定对象数组按升序进行排序。
- static void sort(T[] a, Comparator<? super T> c) :根据指定比较器产生的顺序对指定对象数组进行排序。
数组元素的二分查找
- static int binarySearch(int[] a, int key) 、static int binarySearch(Object[] a, Object key) :要求数组有序,在数组中查找key是否存在,如果存在返回第一次找到的下标,不存在返回负数。
数组的复制
- static int[] copyOf(int[] original, int newLength) :根据original原数组复制一个长度为newLength的新数组,并返回新数组
- static T[] copyOf(T[] original,int newLength):根据original原数组复制一个长度为newLength的新数组,并返回新数组
- static int[] copyOfRange(int[] original, int from, int to) :复制original原数组的[from,to)构成新数组,并返回新数组
- static T[] copyOfRange(T[] original,int from,int to):复制original原数组的[from,to)构成新数组,并返回新数组
比较两个数组是否相等
- static boolean equals(int[] a, int[] a2) :比较两个数组的长度、元素是否完全相同
- static boolean equals(Object[] a,Object[] a2):比较两个数组的长度、元素是否完全相同
填充数组
- static void fill(int[] a, int val) :用val值填充整个a数组
- static void fill(Object[] a,Object val):用val对象填充整个a数组
- static void fill(int[] a, int fromIndex, int toIndex, int val):将a数组[fromIndex,toIndex)部分填充为val值
- static void fill(Object[] a, int fromIndex, int toIndex, Object val) :将a数组[fromIndex,toIndex)部分填充为val对象
四、面向对象的一些小知识
局部变量没有默认值初始化,需要显式赋值。
方法的重载overload 两同一不同(相同的类和方法名,参数个数和参数类型不同)
可变个数形参(jdk5.0) 格式 参数类型 … 参数名
个数可以是0个、1个或多个
static void print(int... nums){
System.out.println(Arrays.toString(nums));
}
高内聚:类的内部数据操作细节自己完成,不允许外部干涉
低耦合:暴漏少量的方法给外部使用,尽量方便外部调用
修饰符 本类内部 本包内 其他包的子类 其他包非子类
在单例模式中,用private,避免在类的外部创建实例
java的引用类型有:类、数组、接口、注解、枚举、记录
五、进阶知识补充
1. this关键字
如果形参和属性名相同的时候,this就会发挥作用
有this修饰代表的是属性变量,没有this修饰则代表形参
this可以调用 成员变量,方法,构造器
this的理解,当前对象或当前正在创建的对象
但是不可以调用static修饰的方法
一般this省略,但是当出现同名了就需要this来区分
this(形参)调用构造器
2.继承
减少了代码冗余,提高代码复用性
继承的出现,有利于功能的拓展
一个父类可以有多个子类,一个子类只可以有一个父类
3.方法重写
override
重写的方法必须与父类方法的返回数据类型相同
不可以重写父类中private修饰的方法
继承之后,子类覆盖父类中同名同参数的方法
4.super关键字的使用
用于在子类重写的时候,对父类的被重写方法调用
区分子类和父类的同名属性(虽然继承了,但是属性不能覆盖)
super也是可以调用属性,方法,构造器
子类构造器的首行,没有this和super 那么就默认调用super()
子类的任何构造器 要么调用自己的构造器要么调用父类的构造器
在使用子类构造器创建对象时,一定在调用子类的时候直接或间接调用到父类的构造器,这样就会将父类的属性和方法加载到内存中,给子类对象使用
public class Father {
private String info="TheFather";
public void setInfo(String info){
this.info=info;
}
public String getInfo(){
return info;
}
}
public class Son extends Father{
private String info="TheSon";
public void test(){
System.out.println(this.getInfo());
System.out.println(super.getInfo());
}
}
Father father = new Father();
Son son = new Son();
son.setInfo("hello");
System.out.println(father.getInfo());//thefather
System.out.println(son.getInfo());//hello
son.test();// hello hello
5.子类对象实例化
从过程角度看,子类构造器创建对象时,子类构造器会直接或间接调用父类的构造器,父类构造器同样会直接或简介调用父类的父类的构造器,直到调用Object类构造器为止
但是最后创建成功 内存中只会有一个对象 就是new的那一个
6.多态性的体现
多态性就是父类引用指向子类的对象
Person p=new man()
编译的时候看左边,运行的时候看右边
使用多态性的前提是,要有继承关系并且有方法的重写
利用这一点,可以根据同样的大类,进行自己的方法重写和调用
例如都是animal,传了dog 那就用dog重写的方法 传了cat 就用cat重写的方法
好处
极大得减少了代码的冗余,不需要定义多个重载的方法
即使增加了新的子类,方法也无需改变,提高了可拓展性,符合开闭原则(对拓展开放,对修改关闭)
弊端
在多态下,创建了子类的对象,加载了子类特有的属性和方法,但是声明的是父类的引用,所以没有办法直接调用子类的特有的属性和方法
7.向下转型
向下转型通过强转换来实现,向下转型可能会出现类型转换异常的问题
建议在向下转型之前用instanceof检查一下
8.Object类
任何一个类都直接或间接继承于Object类,所以叫根父类
Object类没有属性,构造器也是无参的
方法有11个
clone()
实现对象的复制的另一种方法
equals()
任何引用类型都可以用 判断两个对象是否一样
比较的是引用地址是否相同
在String、File、Date和包装类中的equals方法都被重写了,用于比较内容是否一致
==和equals的区别
==是运算符 他的使用范围是基本数据类型和引用类型都可以,在基本数据类型上判断数据值是否相等,引用数据类型比较的是地址值
equals是方法,使用范围只能使用在引用数据类型上。
finalize()
当GC要回收的时候调用这个方法,重写之后可以在释放前做一些操作(System.gc()实现回收 回收null)
可能会到导致出现循环引用,导致此对象不能回收
getClass()
获取当前的类
hashCode()
获取唯一标识哈希值
notify()
用于唤醒一个在此对象监视器上等待的线程
notifyAll()
唤醒在该对象上等待的所有线程
toString()
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
用sout打印变量的时候就是调用了对象的toString()方法,默认返回的是地址值
wait()
wait()
wait()
clone创建对象的使用
package org.example;
import java.lang.reflect.Array;
import java.util.Arrays;
public class App
{
public static void main( String[] args )
{
Father father1=new Father("hello");
try{
Father father2= (Father) father1.clone();
System.out.println(father2.toString());
}catch (Exception e){
e.printStackTrace();
}
}
}
package org.example;
public class Father implements Cloneable{
private String info="TheFather";
public Father(String info) {
this.info = info;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}