常用类
内部类
概念:在一个类内部定义一个类
特点:
- 编译之后可生成访问外部类的字节码文件。
- 内部类可以直接访问外部类的私有成员,而不破坏封装。
- 可为外部类提供必要的内部功能组件。
分为四种:
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
成员内部类
- 在类的内部定义,与实例变量、实例方法同级别的类。
- 外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象。
- 当外部类、内部类存在重名属性时,会优先访问内部类属性。
- 成员内部类不能定义静态成员。
- 代码展示:
package com.zy.ClassTest;
//外部类
public class Outer {
private String name = "外部";
private String phone = "111";
//内部类
class Inner{
private String name = "内部";
private String p = "000";
public void show(){
System.out.println("外部属性:");
//当内部类和外部类属性同名时,会默认调用内部类,使用这种方法调用外部类属性
System.out.println(Outer.this.name);
System.out.println(phone);
System.out.println("内部属性:");
System.out.println(name);
System.out.println(p);
}
}
}
package com.zy.ClassTest;
//创建内部类对象调用方法
public class Test {
public static void main(String[] args) {
// Outer outer = new Outer();
// Outer.Inner inner = outer.new Inner();
//一步创建
Outer.Inner inner = new Outer().new Inner();
inner.show();
}
}
静态内部类
- 不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员。
- 只能直接访问外部类的静态成员(实例成员需实例化外部类对象)。
package com.zy.ClassTest;
//外部类
public class Outer {
private String name = "外部";
private String phone = "111";
//静态内部类,级别相当与外部类
static class Inner{
private String name = "内部";
private String p = "000";
//可以定义静态属性
private static int count = 100;
public void show(){
System.out.println("外部属性:");
//调用外部类属性,需要创建外部类对象,然后用对象调用外部类属性
Outer outer = new Outer();
System.out.println(outer.name);
System.out.println(outer.phone);
System.out.println("内部属性:");
//调用内部类的静态及其他的属性
System.out.println(name);
System.out.println(p);
System.out.println(count);
}
}
}
package com.zy.ClassTest;
public class Test {
public static void main(String[] args) {
// 直接创建静态内部类对象
Outer.Inner inner = new Outer.Inner();
inner.show();
}
}
局部内部类
- 定义在外部类方法中,作用范围和创建对象范围仅限于当前方法。
- 局部内部类访问外部类当前方法中的局部变量时,因无法保障的生命周期域自身相同,变量必须修饰为final。
- 限制类的使用范围,只在方法中使用。
package com.zy.ClassTest;
//外部类
public class Outer {
private String name = "外部";
private String phone = "111";
public void show(){
//定义局部变量
String address = "外地";
//局部内部类,不能加任何访问修饰符
class Inner{
//局部内部类属性
private String phone = "123";
private String email = "@z+y";
public void show2(){
//访问外部类
System.out.println("外部类:");
System.out.println(name);
//外部同名属性,要加上外部类.this,不同名可以省略,同名调用局部内部类的属性
System.out.println(Outer.this.phone);
System.out.println("局部内部类");
System.out.println(phone);
System.out.println(email);
//访问局部变量,jdk1.7以前要加final,变量必须是常量,jdk1.8后自动加上
System.out.println(address);
}
}
//方法内创建局部内部类对象,调用局部内部类的方法
Inner inner = new Inner();
inner.show2();
}
}
package com.zy.ClassTest;
public class Test {
public static void main(String[] args) {
//创建外部类对象
Outer outer = new Outer();
outer.show();
}
}
匿名内部类
- 没有类名的局部内部类(一切特征都与局部内部类相同)。
- 必须继承一个父类或者实现一个接口。
- 定义类、实现类、创建对象的语法合并,只能创建一个该类的对象。
- 优点:减少代码量。
- 缺点:可读性差。
1.接口
package com.zy.ClassTest01;
public interface User {
public void show();
}
2.实现接口的类
package com.zy.ClassTest01;
public class User01 implements User{
@Override
public void show() {
System.out.println("我是01号!");
}
}
3.匿名内部类实现
package com.zy.ClassTest01;
public class UserTest {
public static void main(String[] args) {
// //实现接口的类,创建对象
// User user = new User01();
// user.show();
// //局部内部类
// class User02 implements User{
// @Override
// public void show() {
// System.out.println("我是02!");
// }
// }
// User user = new User02();
// user.show();
//匿名内部类,相当于一个局部内部类
User user = new User() {
@Override
public void show() {
System.out.println("我是匿名!");
}
};
user.show();
}
}
Object类
概述
- 超类、基类,所有类的直接或间接父类,位于继承树的最高层。
- 任何类,如没有书写extends显示继承某个类,都默认直接继承Object类,否则为间接继承。
- Object类中定义的方法,是所有对象都具备的方法。
- Object类型可以存储任何对象。
- 作为参数,可以接受任何对象。
- 作为返回值,可以返回任何对象。
getClass()方法
- public final Class<?> getClass(){}
- 返回引用中存储的实际对象类型。
- 应用:通常用于判断两个引用中实际存储对象类型是否一致。
package com.zy.StudyObjectMethod;
public class TestgetClass {
public static void main(String[] args) {
Student s1 = new Student("lisi",22);
Student s2 = new Student("lisi",22);
//判断是不是同类型
Class c1 = s1.getClass();
Class c2 = s2.getClass();
System.out.println("s1的CLass:"+c1);
System.out.println("s2的CLass:"+c2);
if(c1==c2)
{
System.out.println("s1和s2是同一个类型");
}else{
System.out.println("s1和s2不是同一个类型");
}
}
}
hashCode()方法
- public int hashCode(){}
- 返回该对象的哈希码值。
- 哈希值根据对象的地址或者字符串或者数字使用hash算法计算出来的int类型的数值。
- 一般情况下相同对象返回相同哈希码。
package com.zy.StudyObjectMethod;
public class TestgetClass {
public static void main(String[] args) {
Student s1 = new Student("lisi",22);
Student s2 = new Student("lisi",22);
//hashCode()方法
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
//新创建一个对象,直接赋值s1,hash值是一样的
Student s3 = s1;
System.out.println(s3.hashCode());
//新new一个,任何再赋值,hash值是一样的
Student s4 = new Student();
s4 = s1;
System.out.println(s4.hashCode());
}
}
toString()方法
- public String toString(){}
- 返回该对象的字符串表示(表现形式)。
- 可以根据程序需求覆盖该方法,如:展示对象各个属性值。
package com.zy.StudyObjectMethod;
public class TestgetClass {
public static void main(String[] args) {
Student s1 = new Student("lisi",22);
Student s2 = new Student("zhangsan",24);
//toString()方法
System.out.println(s1.toString());
System.out.println(s2.toString());
//输出:
//com.zy.StudyObjectMethod.Student@7ef20235
//com.zy.StudyObjectMethod.Student@27d6c5e0
//重写toString方法后输出
//Student{name='lisi', age=22}
//Student{name='zhangsan', age=24}
}
}
重写的toString()方法,在Student类里
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
equals()方法
- public boolean equals(Object obj){}
- 默认实现为(this == obj),比较两个对象地址是否相同。
- 可进行覆盖,比较两个对象的内容是否相同。
- 方法覆盖的步骤:
- 比较两个引用是否指向同一个对象。
- 判断obj是否为null
- 判断两个引用指向的实际对象类型是否一致。
- 强制类型转换。
- 依次比较各个属性值是否相同。
package com.zy.StudyObjectMethod;
public class TestgetClass {
public static void main(String[] args) {
// equals()方法
Student s1 = new Student("lisi",22);
Student s2 = new Student("lisi",22);
//直接赋值后,相同
Student s3 = s1;
System.out.println(s1.equals(s2));
System.out.println(s1.equals(s3));
// 没有重写equals方法前,输出结果:
// false
// true
// 重写后的结果:
// true
// true
}
}
在Student类中重写的equals()方法
public boolean equals(Object obj){
//比较两个引用是否指向同一个对象
if(this == obj){
return true;
}
//判断obj是否为null
if(obj == null)
{
return false;
}
//instanceof可以判断是否是某种类型
//判断两个引用指向的实际对象类型是否一致
if(obj instanceof Student)
{
//强制类型转换
Student s = (Student) obj;
// 依次比较各个属性值是否相同
if(this.name.equals(s.getName())&&this.age == s.getAge())
{
return true;
}
}
return false;
}
finalize()方法
- 当对象被判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象,进入回收队列。
- 垃圾对象:没有有效引用指向此对象时,为垃圾对象。
- 垃圾回收:由GC销毁垃圾对象,释放数据存储空间。
- 自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象。
- 手动回收机制:使用System.gc();通知JVM执行垃圾回收。
包装类
- 基本数据类型对应的引用数据类型。
- Object可统一所有数据,包装类的默认值是null。
类型转换,装箱和拆箱
- 装箱就是基本类型转换为包装类型。
- 拆箱就是包装类型转回基本类型。
- jdk1.5之间,我们装箱是用包装类型的构造方法和valueOf(基本类型)来装箱。用对应类型的,例如intValue()方法,将包装类型的转换回基本类型,拆箱。
- jdk1.5之后,系统自动装箱和拆箱,不用自己调用方法,其实就是系统帮你调用了valueOf(Object obj),和例如intValue()这两个方法。
基本类型和字符串的转换
- 八种包装类提供不同类型间的转换方式:
- Number父类中提供6个公性方法。
- parseXXX()静态方法。
package com.zy.ClassTest;
public class packgeTest {
public static void main(String[] args) {
//基本类型转字符串
//1.用+
int n = 12;
String str1 = n + " ";
System.out.println(str1);
//2.用Integer里面的toString()方法
String str2 = Integer.toString(n);
System.out.println(str2);
//后面的是定义将n转为多少进制数
String str3 = Integer.toString(n,16);
System.out.println(str3);
//字符串转基本类型
//使用parseXXX()
String str = "100";//转换的字符串中只能是数字,不能有其他符号,不然会报错
int i = Integer.parseInt(str);
System.out.println(i);
//字符串转为boolean类型,只有为 true时,转换为true,其他无论是什么样的字符串都是”false“
String s1 = "true";
String s2 = "false";
String s3 = "sdf";
String s4 = "vdsvsd";
boolean b1 = Boolean.parseBoolean(s1);
boolean b2 = Boolean.parseBoolean(s2);
boolean b3 = Boolean.parseBoolean(s3);
boolean b4 = Boolean.parseBoolean(s4);
System.out.println(b1);
System.out.println(b2);
System.out.println(b3);
System.out.println(b4);
}
}
整数缓冲区
- Java预见创建了256个常用的整数包装类型对象。
- 在实际应用当中,对已创建的对象进行复用。
package com.zy.IntegerCache;
public class Test {
public static void main(String[] args) {
//比较new的
Integer i1 = new Integer(100);
Integer i2 = new Integer(100);
System.out.println(i1 == i2);
//在-128和127之间的值
Integer i3 = 100;//其实是 Integer i3 = Integer,valueOf(100);
Integer i4 = 100;
System.out.println(i3 == i4);
//超出-128到127范围的
Integer i5 = 200;
Integer i6 = 200;
System.out.println(i5 == i6);
//结果
//false
//true
//false
}
}
String类
概述:
- 字符串是常量,创建之后不可改变。
- 字符串字面值存储在字符串池中,可以共享。
- String s = “Hello”;产生一个对象,字符串池中存储。
- String s = new String(“Hello”);//产生两个对象,堆、池各存储一个。
package com.zy.StringTest;
public class Test {
public static void main(String[] args) {
String name = "lisi";//"lisi"存储在常量池里
System.out.println(name.hashCode());
name = "zhangsan";//“zhangsan”赋值给name变量,并没有修改数据,而是在常量池重新开辟一个空间
System.out.println(name.hashCode());
String name1 = "zhangsan";//会先在常量池中找有没有,有就直接用,没有才开辟空间,所以这个的哈希值是和name一样的,同一个
System.out.println(name1.hashCode());
//new 会在堆和常量池中同时创建一个对象,指向的是堆中的对象地址
//实际上这两个对象可以看成一个,堆中的是指向常量池中的
String str = new String("java");
System.out.println(str.hashCode());
//再使用new会在堆中重新创建一个对象
String str2 = new String("java");
System.out.println(str == str2);//输出是false
//用equals()方法比较是true,因为这个比较的是值
}
}
String常用方法
- public int length();// 返回字符串的长度
- public char charAt();//返回某个位置的字符
- public boolean contains(String str);//判断是否包含某个子字符串
- public char[] toCharArray();//将字符串转换成数组
- public int indexOf(String str); //查找str首次出现的下标,存在,则返回该下标;不存在,则返回-1
- public int lastIndexOf(String str);//查找字符串在当前字符串中最后一次出现的下标索引。
- 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做拆分
- equals(),比较String值是否相同
- compareTo(),比较的String首字符的ASCALL码的差值,如果一样就必须后面不同的对应位置的差值,如果一个到结束都是一样的,就比较长度
package com.zy.StringTest;
public class Test01 {
public static void main(String[] args) {
String str = "java hello,java bye";
System.out.println(str.length());//输出是 19
System.out.println(str.charAt(0));// 输出是 j
System.out.println(str.contains("java"));// 输出 true
char[] c = str.toCharArray();
for (char c1 : c) {
System.out.print(c1);
}
System.out.println("");
//输出 java hello,java bye
System.out.println(str.indexOf("java"));//输出 0
System.out.println(str.lastIndexOf("java"));//输出 11
String str1 = " Java Hello.";
System.out.println(str1.trim());//输出 Java Hello.
System.out.println(str1.toUpperCase());//输出 JAVA HELLO.
System.out.println(str1.endsWith("."));//输出 true
System.out.println(str1.endsWith("sa"));//输出 false
System.out.println(str1.replace("l", "k"));//输出 Java Hekko.
String str2 = "java is best progarming language,java is";
String[] s = str2.split("[ ,]+");//意思是,用空格或多个空格和逗号分隔,
for (String s1 : s) {
System.out.println(s1);
}
//结果:
//java
//is
//best
//progarming
//language
//java
//is
String s1 = "abs";
String s2 = "xyz";
System.out.println(s1.compareTo(s2));//输出 -23
String s3 = "abc";
String s4 = "abx";
System.out.println(s3.compareTo(s4));//输出 --21
String s5 = "abc";
String s6 = "abcsad";
System.out.println(s5.compareTo(s6));//输出 -3
}
}
可变字符串
- StringBuffer:可变长字符串,JDK1.0提供,运行效率慢(相对而言),线程安全。
- StringBuilder:可变长字符串,JDK5.0提供,运行效率快,线程不安全。
package com.zy.StringTest;
//StringBuffer和StringBulider类
public class Test02 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
//append(),添加,不断添加到后面
sb.append("java is good");
sb.append(",hello,world");
System.out.println(sb);//输出:java is good,hello,world
//toString()是将StringBuffer转为String类型,String转StringBuffer可以用构造方法,就是在new的时候传入
System.out.println(sb.toString());//输出:java is good,hello,world
//insert(int i,Object obj)前面一个是你要插入的位置,后面是要插入的对象
sb.insert(0,"001.");
System.out.println(sb.toString());//输出:001.java is good,hello,world
sb.insert(4,"100.");
System.out.println(sb.toString());//输出:001.100.java is good,hello,world
//replace(int i,int j,Object obj);替换,前面i和j是确认替换范围,后面是要替换进去的内容
sb.replace(0,4,"12345.");
System.out.println(sb);//输出:12345.100.java is good,hello,world
//delete(int i,int j);删除,i和j确认删除的范围
sb.delete(0,10);
System.out.println(sb);//输出:java is good,hello,world
//注意:确认的范围都是,包括前面不包含后面
}
}
- 两者的方法是相同的,推荐在单线程时使用StringBuilder
BigDecimal的使用
- double类型的计算会出现精度不足的情况,因为double是取近似值的。
- 当要求精度高的时候,就使用BigDecimal。
- 位置:java.math包中。
- 作用:精确计算浮点数。
- 创建方式:BigDecimal bd = new BigDeccimal(“1.0”);//创建时传入的是String类型,更准确,直接传入可能还是会有偏差。
- 方法:
- BigDecimal add(BigDecimal bd); 加法
- BigDecimal subtract(BigDecimal bd); 减法
- BigDecimal multiply(BigDecimal bd); 乘法
- BigDecimal divide(BigDecimal bd); 除法
- 除法:divide(BigDecimal bd,int scal,RoundingMode mode);
- 参数scal:指定精确到小数点后几位
- 参数mode:
- 指定小数部分的取舍模式,通常采用四舍五入的模式
- 取值为BigDecimal.ROUND_HALF_UP。
package com.zy.StringTest;
import java.math.BigDecimal;
public class Test03 {
public static void main(String[] args) {
BigDecimal bd1 = new BigDecimal("1.0");
BigDecimal bd2 = new BigDecimal("0.9");
//加法
BigDecimal b1 = bd1.add(bd2);
System.out.println(b1);//输出:1.9
//减法
BigDecimal b2 = bd1.subtract(bd2);
System.out.println(b2);//输出:0.1
//乘法
BigDecimal b3 = bd1.multiply(bd2);
System.out.println(b3);//输出:0.90
//除法
BigDecimal b4 = new BigDecimal("1.4").subtract(new BigDecimal("0.5")).divide(bd2,2,BigDecimal.ROUND_HALF_UP);
System.out.println(b4);//输出:1.00
}
}
Date类
- Date表示特定的瞬间,精确到毫秒。Date类中的大部分方法都已经被Calendar类中的方法所取代。
- 时间单位
- 1秒=1000毫秒
- 1毫秒=1000微秒
- 1微妙=1000纳秒
- 大部分方法过时,了解就行,1970(1969是Unix系统的出现)
package com.zy.StringTest;
import java.util.Date;
public class TestDate {
public static void main(String[] args) {
//创建Date对象,就是今天
Date date1 = new Date();
System.out.println(date1);//国外的格式,输出:Thu Apr 01 22:23:25 CST 2021
System.out.println(date1.toLocaleString());//转换为更简易的,输出:2021年4月1日 下午10:23:25
//变为昨天
Date date2 = new Date(date1.getTime()-(60*60*24*1000));
System.out.println(date2.toLocaleString());//输出:2021年3月31日 下午10:23:25
//方法 after,before
boolean b1 = date1.after(date2);
System.out.println(b1);//输出:true
boolean b2 = date1.before(date2);
System.out.println(b2);//输出:false
//比较 compareTo(),输出的1,0,-1,前面大于后面就输出1,不然就输出-1,一样就输出0
}
}
Calender类
- Calender提供了获取或者设置各种日历字段的方法。
- 构造方法
- protected Calender():由于修饰符是protected,所以无法直接创建该对象。
- 其他方法:
package com.zy.StringTest;
import java.util.Calendar;
public class TestCalender {
public static void main(String[] args) {
//不能直接创建对象,调用方法
Calendar calendar = Calendar.getInstance();
System.out.println(calendar);//输出:java.util.GregorianCalendar[time=1617287413394,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2021,MONTH=3,WEEK_OF_YEAR=14,WEEK_OF_MONTH=1,DAY_OF_MONTH=1,DAY_OF_YEAR=91,DAY_OF_WEEK=5,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=10,HOUR_OF_DAY=22,MINUTE=30,SECOND=13,MILLISECOND=394,ZONE_OFFSET=28800000,DST_OFFSET=0]
System.out.println(calendar.getTime().toLocaleString());//输出: 2021年4月1日 下午10:30:13
//获取时间信息,Calender类中设置了很多常量,年月日小时分钟秒的
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);//这个月份是0-11,后面输出要加一
int day = calendar.get(Calendar.DAY_OF_MONTH);
int hour = calendar.get(Calendar.HOUR_OF_DAY);//这个是二十四小时制的,HOUR是十二小时制
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
//修改时间
Calendar calendar1 = Calendar.getInstance();
calendar1.set(Calendar.DAY_OF_MONTH,2);
System.out.println(calendar1.getTime().toLocaleString());//输出: 2021年4月2日 下午10:38:54
//添加或者减少时间
calendar.add(Calendar.HOUR_OF_DAY,1);
System.out.println(calendar.getTime().toLocaleString());//输出:2021年4月1日 下午11:40:28
//补充,获取一个月最大和最小天数
int max = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
int min = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
System.out.println(max);//输出:30(4月30天)
System.out.println(min);//输出:1
}
}
SimpleDateFormat类
- SimpleDateFormat是一个以与语言环境有关的方式来格式化和解析日期的具体类。
- 进行格式化(日期-> 文本)、解析(文本->日期)。
- 常用时间模式字母
package com.zy.StringTest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestSimpleDateFormat {
public static void main(String[] args) throws ParseException {
//创建SimpleDateFormat对象,并定义格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-DD hh-mm-ss");
Date date1 = new Date();
System.out.println(date1);//输出:Fri Apr 02 13:25:54 CST 2021
//日期格式化
String date2 = sdf.format(date1);
System.out.println(date2);//输出:2021-04-92 01-25-54
//解析,将字符串时间转为Date类型
// Date parse = sdf.parse("2021/3/3");//如果传入的字符串格式不对,会抛出异常
// System.out.println(parse);//输出:Unparseable date: "2021/3/3"
Date parse1 = sdf.parse("2021-3-3 13-3-1");//必须按照定义的格式来传入字符串
System.out.println(parse1);//输出:Sun Jan 03 13:03:01 CST 2021
}
}
System类
- System类系统类,主要用于获取系统的属性数据和其他操作,构造方法私有的。
- 方法:
package com.zy.StringTest;
public class TestSystem {
public static void main(String[] args) {
//系统类,不用创建对象因为构造器是私有的
//public static native void arraycopy(Object src, int srcPos,Object dest, int destPos,int length);
//arraycopy()复制数组
//src 源数组,就是被复制的数组
//srcRos 开始复制位置的下标值
//dest 要复制到的数组
//destPos 复制过来的内容存放的位置开始值
//length 复制的内容长度
int[] src = {1,2,3,4,5,6,7};
int[] dest = new int[7];
int[] dest2 = {9,8,7,6,5,4,3};
System.arraycopy(src,0,dest,0,7);
for (int i : dest) {
System.out.print(i+" ");
}
//输出:1 2 3 4 5 6 7
System.out.println("");
System.arraycopy(src,3,dest2,3,4);
for (int i : dest2) {
System.out.print(i+" ");
}
System.out.println("");
//输出:9 8 7 4 5 6 7
//打印系统毫秒数,可以用来计时,在代码块的前后写一个这个语句,相减就能记录代码块的运行时间
System.out.println(System.currentTimeMillis());
//gc()垃圾回收,告诉系统垃圾回收(不一定就回收)
//退出JVM,0是正常退出,非0表示异常退出
System.exit(0);
System.out.println("你好,我退出了");//因为前面执行了退出语句,所以不会执行该语句
}
}