Object类
超类、基类,所有类的直接或间接父类,位于继承树的最顶层。
任何类,如果没有写extend显示继承某个类,都默认直接继承Object类,否则为间接继承。
Object中定义的所有方法,都是对象所具备的方法。
Object类型可以存储任何对象。
作为返回值,可以返回任何对象。
作为参数,可以接受任何对象。
getClass()方法:
public final Class<?> getClass(){}
返回引用中存储的实际对象类型。
应用:通常用于判断俩个引用中实际存储对象类型是否一致。
hashCode()方法
public int hashCode(){}
返回该对象的哈希码值。
哈希值根据对象的地址或字符串或数字使用hash算法计算出来的int类型的数值。
一般情况下相同对象返回相同哈希码值。
toString()方法
public int toString(){}
返回该对象的字符串表示(表现形式)
可以根据程序需求覆盖该方法,如:展示对象各个属性。
equal()方法
public boolean equal(Object object){}
默认实现为(this==object),比较二者地址是否相同。
可进行覆盖,比较俩个对象的内容是否相同。
equal()方法覆盖步骤:
比较两个引用是否指向同一个对象。
判断obj是否为null。
判断两个引用指向的实际对象类型是否一致。
强制类型转换。
依次比较各个属性值是否相同。
@Override
public boolean equals(Object obj) {
//1判断是否为空
if (obj==null){
return false;
}
//2判断是否为同一个对象
if (this==obj){
return true;
}
//3判断是否为Student类型
if(obj instanceof Student){
//4强制转换
Student s = (Student)obj;
//5比较属性
if(this.name.equals(s.getName()) && this.age==s.getAge());{
return true;
}
}
return false;
}
finalize()方法
当对象判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象,进入回收队列。
垃圾对象:没有有效引用指向此对象时,为垃圾对象。
垃圾回收:由GC销毁垃圾对象,释放存储空间。
自动回收机制:JVM内存耗尽,一次性回收所有垃圾对象。
手动回收机制:使用System.gc(); 通知JVM垃圾回收。
包装类
基本数据类型所对应的引用数据类型。
Object可以统一所有数据,包装类的默认值是NULL。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0DgpDoYK-1616019561880)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210316052837853.png)]
装箱和拆箱
装箱,就是把基本类型用它们相对应的引用类型包起来,使它们可以具有对象的特质,如我们可以把int型包装成Integer类的对象,或者把double包装成Double,等等。
拆箱,就是跟装箱的方向相反,将Integer及Double这样的引用类型的对象重新简化为值类型的数据。
public static void main(String[] args) {
int num = 10;
//类型转换:装箱:基本类型转换成引用类型的过程
//使用Integer类创建对象
Integer integer = new Integer(num);
Integer integer1 = Integer.valueOf(num);
System.out.println("装箱");
System.out.println(integer);
System.out.println(integer1);
//类型转换:拆箱,引用类型转换成基本类型
Integer integer2 = new Integer(100);
int int3 = integer2.intValue();
System.out.println("拆箱");
System.out.println(int3);
//JDK1.5之后,提供自动装箱和拆箱
int age = 30;
//自动装箱
Integer integer4 = age;
System.out.println("自动装箱");
System.out.println(integer4);
//自动拆箱
int age2 = integer4;
System.out.println("自动拆箱");
System.out.println(age2);
}
类型转换
8种包装类提供不同类型间的转换方式:
Number父类中提供的6个共性方法。
parseXXX()静态方法。
valueOf()静态方法。
注意:需保证内容的兼容性,否则抛出NumberFormatException异常。
//基本类型和字符串之间的转换
int n = 255;
//用+号
String s1 = n+"";
//使用Integer中的toString()方法
String s2 = Integer.toString(n,16);
System.out.println(s1);
System.out.println(s2);
//字符串转成基本类型
String str = "1000";
//使用Integer.parseXXX()
int n2 = Integer.parseInt(str);
System.out.println(n2);
//boolean字符串转化成基本类型 'true'->true 'false'->false
String str2 = "true";
boolean b1 = Boolean.parseBoolean(str2);
System.out.println(b1);
}
整数缓冲区
Java 预先创建了256个常用的整数包装类型对象。[-128 127]
在实际应该中,对已创建的对象进行复用。
public static void main(String[] args) {
Integer integer1 = new Integer(100);
Integer integer2 = new Integer(100);
System.out.println(integer1==integer2);
Integer integer3 = 100;//自动装箱Integer.valueOf 在堆中有一个缓冲区[-128 127]
Integer integer4 = 100;
System.out.println(integer3==integer4);
Integer integer5 = 200;
Integer integer6 = 200;
System.out.println(integer5==integer6);
}
String类
字符串是常量,创建之后不可以改变。
字符串字面值存储在字符串池中,可以共享。
String s = "Hello"; //产生一个对象,字符串池中储存。
String s = new String("Hello");//产生两个对象,堆,池各储存一个。
String类方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DgCY3hvV-1616019561882)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210317023815397.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gczbVYoi-1616019561883)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210317025003744.png)]
s3,s4比较:第一个字母的ASCALL值如果字母一样比较后一个,值为前一个字母ASCALL值减去s4字母的ASCALL值。
s5,s6比较:前三个字母一样,值就等于s5的长度减去s6的长度。
案例
/**
* 需求:已知String str = “this is a text”
* 1.将str中的单词单独获取出来
* 2.将str中的text替换为practice
* 3.在text前面添加一个easy
* 4.将每个单词的首字母变为大写
*/
public class Test1 {
public static void main(String[] args) {
//1.将str中的单词单独获取出来
String str = "this is a text";
String[] arr=str.split("[ ]+");
for (String s: arr) {
System.out.println(s);
}
//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 upperCase =Character.toUpperCase(first);
System.out.println(upperCase+arr[i].substring(1));
}
}
}
可变字符串
StringBuffer:可变字符串,JDK1.0提供,运行效率慢,线程安全。
StringBuilder:可变字符串,JDK1.5提供,运行效率快,线程不安全。
/**
* StringBuffer和StringBuilder的使用
* 和String区别1.效率比String快。2.比String节省内存。
*/
public class Test1 {
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer();
//1.append();追加
stringBuffer.append("你好!");
System.out.println(stringBuffer);
stringBuffer.append("我好!");
System.out.println(stringBuffer);
//2.insert();添加
stringBuffer.insert(0,"大家好!");
System.out.println(stringBuffer);
//3.replace();替换(包含头不包含尾)
stringBuffer.replace(0,4,"他好!");
System.out.println(stringBuffer);
//4.delete();删除
stringBuffer.delete(0,3);
System.out.println(stringBuffer);
}
}
比较运行速率:
public static void main(String[] args) {
// //开始时间
// long start = System.currentTimeMillis();
// String s = "";
// for (int i=0;i<99999;i++){
// s+=i;
// }
// //结束时间
// long endStart = System.currentTimeMillis();
// System.out.println("用时:"+(endStart-start));//用时:26465
//开始时间
// long start = System.currentTimeMillis();
// StringBuilder s = new StringBuilder();
// for (int i=0;i<999999;i++){
// s.append(i);
// }
// //结束时间
// long endStart = System.currentTimeMillis();
// System.out.println("用时:"+(endStart-start));//用时:40
//开始时间
long start = System.currentTimeMillis();
StringBuffer s =new StringBuffer();
for (int i=0;i<999999;i++){
s.append(i);
}
//结束时间
long endStart = System.currentTimeMillis();
System.out.println("用时:"+(endStart-start));//用时:68
}
StringTokenizer
作用:分切字符串
public static void main(String[] args) {
String http="http://www.baidu.com/? name=wenber&age=19&code=7749 ";
//找到分割符
int index = http.indexOf("?");
//+1表示去掉问号
String content = http.substring(index+1);
//创建切割字符串对象:1.需要切割的字符串2:用什么字符串来切割3:是否返回标记
//true返回分隔符 false不返回
StringTokenizer stringTokenizer = new StringTokenizer(content,"&",true);
while (stringTokenizer.hasMoreElements()){
//取得每个内容
String msg = (String) stringTokenizer.nextElement();
System.out.println(msg);
}
}
Properties
简介
Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
一个属性列表可包含另一个属性列表作为它的“默认值”;如果未能在原有的属性列表中搜索到属性键,则搜索第二个属性列表。
因为 Properties 继承于 Hashtable,所以可对 Properties 对象应用 put 和 putAll 方法。但不建议使用这两个方法,因为它们允许调用者插入其键或值不是 String 的项。相反,应该使用 setProperty 方法。如果在“不安全”的 Properties 对象(即包含非 String 的键或值)上调用 store 或 save 方法,则该调用将失败。类似地,如果在“不安全”的 Properties 对象(即包含非 String 的键)上调用 propertyNames 或 list 方法,则该调用将失败。
/**
* 测试java工具类中的properties属性对象
* @author wenber
*
*/
public class TestProperties {
public static void main(String[] args) {
//testStore();
testRead();
}
/**
* 从文件中读取
*/
public static void testRead(){
try {
//创建属性对象
Properties pro=new Properties();
//从文件中加载内容
pro.load(new FileInputStream("d://wife.txt"));
//读取内容
String ip=pro.getProperty("ip");
System.out.println(ip);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 测试将内容存储的文件中
*/
private static void testStore() {
try {
//创建属性对象
Properties pro=new Properties();
//向属性对象中写入值
pro.setProperty("ip","192.168.1.2");
pro.setProperty("url","http://www.joinlabs3.com");
//1:存到哪里 2:文件描述
pro.store(new FileOutputStream("d://wife.txt"), "wenber store zf wife");
} catch (Exception e) {
e.printStackTrace();
}
}
}
项目中应用案例
/**
* 专用于配置文件的读写
* @author wenber
*
*/
public class ConfigUtils {
/**
* 专用于取得字符串类型时值
* @param name 属性名
* @return 属性值
*/
public static String getStringValue(String name){
return prop.getProperty(name);
}
/**
* 专用于取得数字整型配置信息
* @param name 属性名
* @return 属性值
*/
public static int getIntValue(String name){
try{
Integer value=Integer.parseInt(prop.getProperty(name));
return value;
}catch(NumberFormatException e){
e.printStackTrace();
}
return -1;
}
BigDecimal
位置:java.math包中。
作用:精确计算浮点数。
创建方式:
BigDecimal bd = new BigDecimal("1.0");
public static void main(String[] args) {
BigDecimal bd = new BigDecimal("1.9");
BigDecimal bd2 = new BigDecimal("1.7");
//减法
BigDecimal r1=bd.subtract(bd2);
System.out.println(r1);
//加法
BigDecimal r2=bd.add(bd2);
System.out.println(r2);
//乘法
BigDecimal r3=bd.multiply(bd2);
System.out.println(r3);
//除法 ROUND_HALF_UP四舍五入
BigDecimal r4=bd.divide(bd2,2,BigDecimal.ROUND_HALF_UP);
System.out.println(r4);
//面试题
double result = (1.4-0.5)/0.9;//double只会计算出近似值
System.out.println(result);
System.out.println("-------");
BigDecimal r5 = new BigDecimal("1.4")
.subtract(new BigDecimal("0.5"))
.divide(new BigDecimal("0.9"));
System.out.println(r5);
}
除法:divide(BigDecimal bd , int scal ,RoundingMode mode)
参数scal:指定精确到小数点后几位。
参数mode:
指定小数部分取舍模式,通常采用四舍五入模式。
取值为BigDecimal.ROUND_HALF_UP。
Date
Date表示特定的瞬间,精确到毫秒。Date类中的大部分方法都已经被Calendar类中的方法所取代。
时间单位:
1秒=1000毫秒
1毫秒=1000微秒
1微秒=1000纳秒
public static void main(String[] args) {
//今天
Date date = new Date();
System.out.println(date.toString());
System.out.println(date.toLocaleString());
//昨天
Date date2 = new Date(date.getTime()-(60*60*24*1000));
System.out.println(date2.toLocaleString());
//方法before after
boolean b1 = date.after(date2);
boolean b2 = date.before(date2);
System.out.println(b1);
System.out.println(b2);
//比较compareTo
int d = date.compareTo(date2);
System.out.println(d);
//比较是否相等equals
boolean b3=date.equals(date2);
System.out.println(b3);
//通过使用setTime()方法是设置
//之后的时间(以毫秒为单位)
date.setTime(15000);
System.out.println(date);
}
Calendar
提供了获取或设置各种日历字段的方法。
构造方法:
protected Calendar():由于修饰符是protected,所以无法直接创建该对象。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2ldIo1eb-1616019561885)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210317233609469.png)]
public static void main(String[] args) {
//创建Calendar
Calendar calendar = Calendar.getInstance();
System.out.println(calendar.getTime().toLocaleString());
//获取年
int year = calendar.get(calendar.YEAR);
//月 0-11
int month = calendar.get(calendar.MONTH);
//日
int day = calendar.get(calendar.DAY_OF_MONTH);
//时
int hour = calendar.get(calendar.HOUR_OF_DAY);
//分
int minute = calendar.get(calendar.MINUTE);
//秒
int second = calendar.get(calendar.SECOND);
System.out.println(year+"年"+(month+1)+"月"+day+"日"+hour+"时"+"分"+second+"秒");
//add方法修改时间
calendar.add(calendar.YEAR,1);
System.out.println(calendar.getTime().toLocaleString());
// 补充方法
System.out.println(calendar.getActualMaximum(calendar.DAY_OF_MONTH));
System.out.println(calendar.getActualMinimum(calendar.DAY_OF_MONTH));
}
SimpleDateFormat
SimpleDateFormat是一个以语言环境有关的方式来格式化和解析日期的具体类。
进行格式化(日期—>文本)、解析(文本—>日期)。
常用的时间模式字母:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cgWhphSP-1616019561887)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210317234003729.png)]
public static void main(String[] args) throws Exception {
//创建SimpleDateFormat
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yy年MM月dd日 mm:ss:SS");
//创建日期
Date date = new Date();
System.out.println(date);
//格式化
System.out.println(simpleDateFormat.format(date));
//解析
System.out.println(simpleDateFormat.parse("1997年09月25日 23:15:56"));
}
System类
System系统类,主要用于获取系统的属性数据和其他操作,构造方法是私有的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SNVUcMoL-1616019561888)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210318034757941.png)]
public static void main(String[] args) {
/**
* arraycopy:数组的复制
* src:源数组
* srcPos:从哪个位置开始复制
* dest:目标数组
* destPos:目标数组位置
* length:复制的长度
*/
int[] arr = {1,2,6,4,8};
int[] arr2=new int[5];
System.arraycopy(arr,0,arr2,0,3);
for (int i : arr2){
System.out.println(i);
}
//获取毫秒数
System.out.println(System.currentTimeMillis());
//垃圾回收
new Student("小敏",10);
System.gc();
//退出JCM 0表示正常退出 非0表示异常退出
System.exit(0);
System.out.println("你好");
}
枚举
简介
public static final int SEASON_SPRING = 1;
public static final int SEASON_SUMMER = 2;
public static final int SEASON_FALL = 3;
public static final int SEASON_WINTER = 4;
枚举类更加直观,类型安全。使用常量会有以下几个缺陷:
-
类型不安全。若一个方法中要求传入季节这个参数,用常量的话,形参就是int类型,开发者传入任意类型的int类型值就行,但是如果是枚举类型的话,就只能传入枚举类中包含的对象。
-
没有命名空间。开发者要在命名的时候以SEASON_开头,这样另外一个开发者再看这段代码的时候,才知道这四个常量分别代表季节。
特点
enum和class、interface的地位一样
使用enum定义的枚举类默认继承了java.lang.Enum,而不是继承Object类。枚举类可以实现一个或多个接口。
枚举类的所有实例都必须放在第一行展示,不需使用new 关键字,不需显式调用构造器。自动添加public static final修饰。
使用enum定义、非抽象的枚举类默认使用final修饰,不可以被继承。
枚举类的构造器只能是私有的。
public enum SeasonEnum {
SPRING("春天"),SUMMER("夏天"),FALL("秋天"),WINTER("冬天");
//定义的属性也是不可变的
private final String name;
SeasonEnum(String name){
this.name=name;
}
/**
* 定义方法
* @return
*/
public String getName(){
return name;
}
}
案例一
枚举类内也可以定义属性和方法,可是是静态的和非静态的。
public enum SeasonEnum {
SPRING("春天"),SUMMER("夏天"),FALL("秋天"),WINTER("冬天");
//定义的属性也是不可变的
private final String name;
SeasonEnum(String name){
this.name=name;
}
/**
* 定义方法
* @return
*/
public String getName(){
return name;
}
}
/**
* 测试
* @author wenber
*
*/
public class TestEnum2 {
public static void main(String[] args) {
SeasonEnum season=SeasonEnum.SPRING;
//取得季节实例中的属性
//System.out.println(season.getName());
//传季节枚举实例
switch(season){
//判断识别
case SPRING:
System.out.println(season.getName());
break;
case SUMMER:
System.out.println(season.getName());
break;
}
}
}
案例2
枚举类可以实现一个或多个接口。与普通类一样,实现接口的时候需要实现接口中定义的所有方法,若没有完全实现,那这个枚举类就是抽象的,只是不需显式加上abstract修饰,系统化会默认加上。
package base;
/**
* 实现了抽象方法的枚举
* @author wenber
*
*/
public enum Operation {
//相加
PLUS{
@Override
public double eval(double x, double y) {
return x+y;
}
},
//相减
MINUS{
@Override
public double eval(double x, double y) {
return x-y;
}
},
//相乘
TIMES{
@Override
public double eval(double x, double y) {
return x*y;
}
},
//相除
DIVIDE{
@Override
public double eval(double x, double y) {
return x/y;
}
};
//在枚举中定义抽象的方法
public abstract double eval(double x,double y);
}
package base;
/**
* 测试枚举中实现抽象的方法
* @author wenber
*
*/
public class TestEnum3 {
public static void main(String[] args) {
//调用枚举中的方法【方便 好记】
System.out.println(Operation.PLUS.eval(4, 2));
System.out.println(Operation.TIMES.eval(4, 2));
System.out.println(Operation.MINUS.eval(4, 2));
System.out.println(Operation.DIVIDE.eval(4, 2));
}
}
总结:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ezs0ymYu-1616019561890)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210318040325730.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V4RD0xe6-1616019561891)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210318040339085.png)]