内部类
为什么要有内部类?
如身体和头、手、脚的关系,属于包含关系,不是继承关系,所以就产生了内部类的需求。
内部类的分类
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
什么是内部类?
概念:在一个类的内部再定义一个完整的类。
特点:
(1)编译之后可生成独立的字节码文件(.class文件)。
(2)内部类可直接访问外部类的私有成员,而不破坏封装。
(3)可为外部类提供必要的内部功能组件。
成员内部类
- 在类的内部定于,与实例变量、实例方法同级别的类
- 外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象。即要先创建外部类对象,才能创建内部类对象。
- 创建对象过程:
(方法一)
1.创建外部类对象:Outer outer = new Outer();
2.创建内部类对象:Inner inner = outer.new Inner();
(方法二)
一步到位版:Inner inner = new Outer().new Inner(); - 当外部类、内部类存在重名属性时,会优先访问内部类属性。如要访问外部类的属性时,则需要用【外部类类名.this.属性名】来访问。
- 成员内部类不能定义静态成员,但可以包涵静态常量。
静态内部类(相当于外部类)
- 不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员。(相当于外部类)既然和外部类一样的级别,为什么还要定义静态内部类呢?答案:作用是为了给外部类提供功能和使用。
- 创建过程:Outer.Inner inner = new Outer.Inner();
- 注意:只有内部类才可用static修饰,普通的类(外部类)不可以用static修饰
- 只能直接访问外部类的静态成员(实例成员需实例化外部类对象)。这可就是静态内中不能访问非静态成员。
局部内部类
定义在外部类方法中,作用范围和创建对象范围仅限于当前方法。
- 注意:在局部中的成员不能加任何访问修饰符,如局部变量、局部类前面都不可以加访问修饰符。
- 局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final。(常量)
- 限制类的使用范围,只能在当前的方法中使用,在当前方法中声明和实例化局部内部类,则调用要执行的方法。
匿名内部类
-
没有类名的局部内部类(一切特征都与局部内部类相同)。
-
必须继承一个父类或者实现一个接口。
-
定义类、实现类、创建对象的语法合并,只能创建一个该类的对象。
(1)优点:减少代码量。
(2)缺点:可读性较差。 -
作用:将只执行一次的局部内部类,进行优化,优化后即为匿名内部类。
Object类
介绍
- 超类、基类,所有类的直接或者间接父类,位于继承树的最顶层。
- 任何类,如没有书写extends显示继承某个类,都是默认直接继承Object类,否则为间接继承。
- Object类中所定义的方法,是所有对象都具备的方法。
- Object类型可以存储任何对象。
(1)作为参数,可接受任何对象。
(2)作为返回值,可返回任何对象。
方法
getClass()方法
- public final Class<?> getClass(){}
- 返回引用中存储的实际对象类型。
- 应用:通常用于判断两个引用中实际存储对象类型是否一致(和instanceof类似)。
hashCode()方法
- public int hashCode(){}
- 返回该对象的哈希码值。
- 哈希值根据对象的地址或字符串或数字使用hash算法计算出来的int类型的数值。
- 一般情况下相同对象返回相同哈希码。(相同对象即地址相同)。
toString()方法
- public String toString(){}
- 返回该对象的字符串表示(表现现式)。
- 可以根据程序需求覆盖该方法,如:展示对象各个属性值。
equals()方法
- public boolean equals(Object obj){}
- 默认实现为(this==obj),比较两个对象地址是否相同。
- 可进行覆盖,比较两个对象的内容是否相同。
- equals()方法覆盖步骤:
(1)比较两个引用是否指向同一个对象。
(2)判断obj是否为unll。
(3)判断两个引用指向的实际对象类型是否一致。
(4)强制类型转换。
(5)依次比较各个属性值是否相同。
finalize()方法
- 当对象被判定为垃圾对象时,由Java自动调用此方法,用以标记垃圾对象进入回收队列。
- 垃圾对象:没有有效引用指向此对象时,为垃圾对象。
- 垃圾回收:由GC销毁垃圾对象,释放数据存储空间。
- 自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象。
- 手动回收机制:使用System.gc();通知JVM执行垃圾回收。
包装类
什么是包装类?
- 基本数据类型所对应的引用数据类型。
- Object可统一所有数据,包装类的默认值为null。
作用:基本数据类型是没有任何方法可调用的,转化为包装类后,变成了引用对象,即可调用提供的方法。
类型转换与装箱、拆箱
- 装箱:将基本数据类型转成引用类型的过程。
- 拆箱:将引用类型转换为基本类型的过程。
8种包装类提供不同类型间的转换方式:
(1)Number父类中提供的6个共性方法
(2)parseXXX()静态方法–拆箱
(3)valueOf()静态方法–装箱
注意:需保证类型兼容,否则抛出NumberFormatException异常。
面试题
Integer integer1 = new Integer(100);
Integer integer2 = new Integer(100);
Sysiem.out.println(integer1==integer2);//false
Integer integer3 = 100;//自动装箱
Integer integer4 = 100;
Sysiem.out.println(integer3==integer4);//true
Integer integer5 = 200;//自动装箱
Integer integer6 = 200;
Sysiem.out.println(integer5==integer6);//false
解释:在这里自动装箱语句Integer integer3 = 100;相当于Integer integer3 = Integer.valueOf(100);不是使用Integer()构造方法,此时使用valueOf()方法则会在缓存区找,缓存区的范围为-126~125,则找到了就用缓存区里的固定地址,而200超出了,则各自重新创建一个内存存放。
整数缓冲区:
(1)Java预先创建了256个常用的整数包装类型对象。
(2)在实际应用中,对已创建的对象进行复用。
String类
- 字符串是常量,创建之后不可改变。
- 字符串字面值存储在字符串池中,可以共享。
- String s= “Hellow”;产生一个对象,字符串池中存储。
- String s = new String (“Hellow”);产生两个对象,堆、池(栈)各存放一个,堆中存放的也是地址。
- 面试题`
String name = "Hellow";//"Hellow"常量存储在字符串池中
name = "zhangsan";//"zhangsan"赋值给name变量,给字符串赋值时,并没有修改数据,而是重新开辟一个空间
String name2 = "zhangsan";
System.out.println(name == name2);//true
String str = new String("Java");
String str2 = new String("Java");
System.out.println(str== str2);//false
System.out.println(str.equals(str2));//true
常用方法
- public int length();返回字符串的长度。
- public char charAt(int indext);根据下标获取字符。
- public boolean contains(String str);判断当前字符串中是否包含str。
- public char[] toCharArray();将字符串转换成字符数组。
- public int indexOf(String str);查找str首次出现的下标,存在,则返回该下标,不存在,则返回-1。
- public int lastIndexOf(String str);查找str最后一次出现的下标,存在,则返回该下标,不存在,则返回-1。
- public String trim();去除字符串前后的空格。
- public String toUpperCase();将小写转化为大写。
- public boolean endWith(String str);判断字符串是否以str结尾。
- public String replace(char oldChar,char newChar);将就字符串替换成新字符串(全部都替换掉)。
- public String[] split(String str);根据str做分割。
特殊方法
- split方法
String say = " Java is the best pragraming language,java xiong";
String [] arr = say.split("[ ,]+");
说明:其中的【】表示选择,现在【】中有空格和逗号,所以可以以空格或逗号分割,同时后面加了(+)加号表示可以匹配多个连续的空格或逗号。
- equals,比较内容是否相同,区分大小写。
- equalsIgnoreCase,比较内容是否相同,忽略大小写。
- compare(),比较大小
说明:
//情况一
String s1 = "abc",s2="xyz";
System.out.println(s1.compare(s2));//-23
/*
因为先一个个比较,从左到右,先‘a’与‘x’比,a为97(字节码编号),x为120,则97-120=-23
比完第一个后,发现不同,就不会往下比较了,如相同继续比较下面的。
*/
//情况二
String s3 = "abc",s4 = "abc";
System.out.println(s3.compare(s4));//0
//情况三
String s5 = "abc",s6 = "abcdef";
System.out.println(s5.compare(s6));//-3
/*
全部都相同,s5已经没有了,这是就比较长度,s5剩下0,s6剩下3,则0-3=-3
*/
案例演示
需求:
已知String str = “this is a text”;
- 将str中的单词独立获取出来。
- 将str中的text替换为practice。
- 在text前面插入一个easy。
- 将每个单词的首字母改为大写。
String str = "this is a text";
//1. 将str中的单词独立获取出来。
String [] arr = str.split(" ");
for(int i = 0;i<arr.length;i++){
System.out.println(arr[i]);
}
//2. 将str中的text替换为practice。
String str2 = str.replace("text","practice");
System.out.println(str2);
//3. 在text前面插入一个easy。
String str3 = str.replace("text","easy text");
System.out.println(str3);
//4. 将每个单词的首字母改为大写。
for(int i=0;i<arr.length;i++) {
char first = arr[i].charAt(0);
char upperFirst = Character.toUpperCase(first);
String news = upperFirst + arr[i].substring(1);
System.out.println(news);
}
可变字符串
- StringBuffer:可变长度字符串,JDK1.0提供,运行效率慢、线程安全。
- StringBuilder:可变长度字符串,JDK1.5提供,运行效率高、线程不安全。
方法:
- append()追加
- insert(index,str)添加
- replace(star,end,str)替换
- delete(star,end)删除
- reverse()反转
- System.currentTimeMillis()时间,返回值为long/int
推荐:
https://blog.csdn.net/itchuxuezhe_yang/article/details/89966303
BigDecimal(精度更高的类)
//思考一下:下列程序的输出结果为多少?
double d1 = 1.0;
double d2 = 0.9;
System.out.println(d1-d2);//输出结果为:0.09999999999999998
说明:很多实际应用中需要精确运算,而double是近似储存,不在符合要求,则需要借助BigDecimal。
- 位于:java.math包中。
- 作用:精确计算浮点数。
- 创建方式以及方法:
BigDecimal bd1 = new BigDecimal("1.0");//可以使用8种基本数据类型,这里使用了字符串,
//在创建中建议使用字符串创建,如给了double的1.0可能给的就是一个近似值,计算出来一样会造成误差。
BigDecimal bd2 = new BigDecimal("3.0");
//减法
BigDecimal r1 = bd1.subtract(bd2);
//加法
BigDecimal r2 = bd1.add(bd2);
//乘法
BigDecimal r3 = bd1.multiply(bd2);
//除法
//BigDecimal r4 = bd1.divide(bd2);//在这里1.0/3.0是除不尽的,则会报出异常,
//可用保留小数点的构造方法
BigDecimal r4 = bd1.divide(bd2,2,BigDecimal.ROUND_HALF_UP);
//2表示保留两位小数点,ROUND_HALF_UP表示以四舍五入的方式
Date类
- Date表示特定的瞬间,精确到毫秒。Date类中的大部分方法都已经被Calendar类中的方法取代。(因为Date设计的有缺陷)
- 时间单位
(1)1秒 = 1000毫秒
(2)1毫秒 = 1000微秒
(3)1微秒 = 1000纳秒 - 方法
(1)after()
(2)before()
(3)compareTo()比较
(4)equals()是否相同
Calendar类
- Calendar提供了获取或设置各种日历字段的方法。
- 构造方法:protected Calendar(),由于修饰符是protected,所以无法直接创建对象
- 其他方法
方法名 | 说明 |
---|---|
Static Calendar getInstance() | 使用默认时区和区域获取日历 |
Viod set(int y,int m,int d,int h,int m,int s) | 设置日历的年、月、日、时、分、秒 |
Int get(int field) | 返回给定日历字段的值。字段比如年、月、日等 |
Void setTime(Date date) | 用给定的Date设置此日历的时间。 |
Date getTime() | 返回一个Date表示此日历的时间。 |
Viod add(int field,int amount) | 按照日历的规则,给指定字段添加或减少时间量 |
Long getTimeInMillies() | 毫秒为单位返回该日历的时间值 |
Int getActualMaximum(int field) | 获取某月(field)的最大天数 |
Int getActualMinimum(int field) | 获取某月的最小天数(也就是1) |
-------- | ----- |
说明 | field可以是Calendar中的常量,如YEAR(年)、MONTH(月)、DAY_OF_MONTH(日)等,语法:Calendar. YEAR获取年;Calendar. MONTH获取月,月份是从0开始,所以要+1. |
SimpleDateFormat(简化日期格式)
- SimpleDateFormat是一个以语言环境有关的方式来格式化和解析日期的具体类。
- 进行格式化(日期→文本)、解析(文本→日期)。
- 常用的时间模式字母
字母 | 日期或时间 |
---|---|
y | 年 |
M | 月 |
d | 日 |
H | 一天中小时数(0-23) |
m | 分钟 |
s | 秒 |
S | 毫秒 |
创建过程
package chap01;
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import javax.xml.crypto.Data;
public class hello {
public static void main(String[] args) {
//1.创建SimpleDateFormat对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
//2.创建Date
Date date = new Date();
//3.格式化Date,format()方法(把日期转成字符串)
String str=sdf.format(date);
//4.解析(把字符串转成日期)parse()方法
try {
Date data2=sdf.parse(str);
} catch (ParseException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
System.out.println(str);//2020年11月09日 21:38:32
}
}
System类
- System系统类,主要用于获取系统的属性数据和其他操作,构造方法私有的
- 方法
static void arraycopy(…);复制数组
static long currentTimeMillis();获取当前系统时间,返回的是毫秒值
static void gc();建议JVM赶快启动垃圾回收
static void exit();退出JVM,如果参数为0表示正常退出,非0表示异常退出。
结束语
谢谢。。。