构造函数。
@HotSpotIntrinsicCandidate public Object() {}
@HotSpotIntrinsicCandidate属于注解,暂时跳过,之后会总结。
返回此Object的运行时类。 返回的类对象是被表示类的static synchronized方法锁定的对象。 final关键字让继承Object类的子类无法重写该方法。
返回此Object的运行时类。 返回的类对象是被表示类的static synchronized方法锁定的对象。 final关键字让继承Object类的子类无法重写该方法。
@HotSpotIntrinsicCandidate public final native Class<?> getClass();
hash拓展
Hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
比如要存储100个不同数据,如果存第100个,就要和99个对比,效率比较低,但是如果我提供10个哈希表,分别存储十位从0到9的数,那么先算出第一百个数在哪个哈希表里,然后再去相应的哈希表里找就好了。
@HotSpotIntrinsicCandidate public native int hashCode();
返回对象的哈希码值。 支持这种方法是为了散列表,如HashMap提供的那样 。不同的对象,哈希值可能相同。
判断两个类是否相等,很多类都会重写这个方法。可以看出Object类中,比较的是引用是否相等,而不是值是否相等。
public boolean equals(Object obj) { return (this == obj); }
复制一个一样的类出来
@HotSpotIntrinsicCandidate protected native Object clone() throws CloneNotSupportedException;
new操作符的本意是分配内存。程序执行到new操作符时, 首先去看new操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间。分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化,构造方法返回后,一个对象创建完毕,可以把他的引用(地址)发布到外部,在外部就可以使用这个引用操纵这个对象。
而clone在第一步是和new相似的, 都是分配内存,调用clone方法时,分配的内存和原对象相同,然后再使用原对象中对应的各个域,填充新对象的域, 填充完成之后,clone方法返回,一个新的相同的对象被创建,同样可以把这个新对象的引用发布到外部。
如果一个对象的成员变量有对象,要重写clone方法,比如
class Employee implements Cloneable { public Object clone() throws CloneNotSupportedException { Employee cloned = (Employee) super.clone(); cloned.hireDay = (Date)hireDay.clone() return cloned; } }
类名加@加哈希字符串
public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); }
唤醒在该对象上等待的单个线程。
@HotSpotIntrinsicCandidate public final native void notify();
唤醒该对象上等待的所有线程。
@HotSpotIntrinsicCandidate public final native void notifyAll();
当前线程等待,直到另一个线程调用该对象的notify()方法或notifyAll()方法。
public final void wait() throws InterruptedException { wait(0L); }
当前线程等待,最多timeoutMillis毫秒。可以被notify()方法或notifyAll()方法唤醒。
public final native void wait(long timeoutMillis) throws InterruptedException;
阻塞当前线程 timeoutMillis毫秒,nanos(0-999999)纳秒 。 可以被notify()方法或notifyAll()方法唤醒。但是从源码可以看出,当纳秒大于零的时候,相当于阻塞了毫秒数加一。
public final void wait(long timeoutMillis, int nanos) throws InterruptedException { if (timeoutMillis < 0) { throw new IllegalArgumentException("timeoutMillis value is negative"); } if (nanos < 0 || nanos > 999999) { throw new IllegalArgumentException( "nanosecond timeout value out of range"); } if (nanos > 0 && timeoutMillis < Long.MAX_VALUE) { timeoutMillis++; } wait(timeoutMillis); }
当垃圾收集确定不再有对该对象的引用时,垃圾收集器在对象上调用该对象。
@Deprecated(since="9") protected void finalize() throws Throwable { }
每个包装类的对象可以封装一个相应的基本类型的数据,并提供了其它一些有用的方法。包装类对象一经创建,其内容(所封装的基本类型数据值)不可改变。、
内容不可改变的原因
所有包装类存放的数值都是final类型。
测试
package JavaObjectTest; public class ObjectTest { public static void main(String[] args) { int m = 500; Integer obj = new Integer(m); // 手动装箱,在version9之后被弃用 int n = obj.intValue(); // 手动拆箱 Integer obj1 = 100; //自动装箱 m = obj1; //自动拆箱 System.out.println(" "+m+ obj1 + obj + n); } }
包装类太多了,以Integer为例查看源码
发现有非常多的变量和函数,有类型转换的,简单的比较等操作。
常用函数
这些函数或者变量都是static类型,可以不创建类的实例直接调用。
Math.PI 记录的圆周率 Math.E 记录e的常量 Math中还有一些类似的常量,都是一些工程数学常用量。 Math.abs 求绝对值 Math.sin 正弦函数 Math.asin 反正弦函数 Math.cos 余弦函数 Math.acos 反余弦函数 Math.tan 正切函数 Math.atan 反正切函数 Math.atan2 商的反正切函数 Math.toDegrees 弧度转化为角度 Math.toRadians 角度转化为弧度 Math.ceil 得到不小于某数的最大整数 Math.floor 得到不大于某数的最大整数 Math.IEEEremainder 求余 Math.max 求两数中最大 Math.min 求两数中最小 Math.sqrt 求开方 Math.pow 求某数的任意次方, 抛出ArithmeticException处理溢出异常 Math.exp 求e的任意次方 Math.log10 以10为底的对数 Math.log 自然对数 Math.rint 求距离某数最近的整数(可能比某数大,也可能比它小) Math.round 同上,返回int型或者long型(上一个函数返回double型) Math.random 返回0,1之间的一个随机数
存储日期相关的信息,其中有的变量被transient修饰,不能被持久化
SimpleDateFormat 允许你选择任何用户自定义日期时间格式来运行。
package JavaObjectTest; import java.text.SimpleDateFormat; import java.util.Date; public class ObjectTest { public static void main(String[] args) { Date dateNow = new Date( ); SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss"); System.out.println("当前时间为: " + ft.format(dateNow)); } }
字母 描述 示例
G 纪元标记 AD
y 四位年份 2001
M 月份 July or 07
d 一个月的日期 10
h A.M./P.M. (1~12)格式小时 12
H 一天中的小时 (0~23) 22
m 分钟数 30
s 秒数 55
S 毫秒数 234
E 星期几 Tuesday
D 一年中的日子 360
F 一个月中第几周的周几 2 (second Wed. in July)
w 一年中第几周 40
W 一个月中第几周 1 a A.M./P.M. 标记 PM
k 一天中的小时(1~24) 24
K A.M./P.M. (0~11)格式小时 10
z 时区 Eastern Standard Time
’ 文字定界符 Delimiter
" 单引号 `
Calendar类是一个抽象类,在实际使用时实现特定的子类的对象,创建对象的过程对程序员来说是透明的,只需要使用getInstance方法创建即可。
测试
package JavaObjectTest; import java.util.Calendar; public class ObjectTest { public static void main(String args[]) { Calendar c = Calendar.getInstance(); //默认是当前日期 System.out.println(c); } }
输出
java.util.GregorianCalendar[time=1618042749377,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=15,WEEK_OF_MONTH=2,DAY_OF_MONTH=10,DAY_OF_YEAR=100,DAY_OF_WEEK=7,DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=4,HOUR_OF_DAY=16,MINUTE=19,SECOND=9,MILLISECOND=377,ZONE_OFFSET=28800000,DST_OFFSET=0]
当我尝试查看源码的时候,发现这个类比Date类实在是复杂太多,功能相当强大,暂不深究,使用的时候再看。
代码
package JavaObjectTest; import java.text.SimpleDateFormat; import java.util.Date; public class ObjectTest { public static void main(String args[]) { // 初始化 Date 对象 Date date = new Date(); //c的使用 System.out.printf("全部日期和时间信息:%tc%n",date); //f的使用 System.out.printf("年-月-日格式:%tF%n",date); //d的使用 System.out.printf("月/日/年格式:%tD%n",date); //r的使用 System.out.printf("HH:MM:SS PM格式(12时制):%tr%n",date); } }
输出
代码
cpppackage JavaObjectTest; import java.text.SimpleDateFormat; import java.util.Date; public class ObjectTest { public static void main(String args[]) { try { System.out.println(new Date( ) ); Thread.sleep(1000*3); // 休眠3秒 System.out.println(new Date( ) ); } catch (Exception e) { System.out.println("Got an exception!"); } } }
结果
string的value存放方式是byte类型的数组:
String() //初始化一个新创建的 String 对象,使其表示一个空字符序列。 String(byte[] bytes) //通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。 String(byte[] bytes, Charset charset) //通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。 String(byte[] bytes, int offset, int length) //通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的 String。 String(byte[] bytes, int offset, int length, Charset charset) //通过使用指定的 charset 解码指定的 byte 子数组,构造一个新的 String。 String(byte[] bytes, int offset, int length, String charsetName) //通过使用指定的字符集解码指定的 byte 子数组,构造一个新的 String。 String(byte[] bytes, String charsetName) //通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。 String(char[] value) //分配一个新的 String,使其表示字符数组参数中当前包含的字符序列。 String(char[] value, int offset, int count) //分配一个新的 String,它包含取自字符数组参数一个子数组的字符。 String(int[] codePoints, int offset, int count) //分配一个新的 String,它包含 Unicode 代码点数组参数一个子数组的字符。 String(String original) //初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建 的字符串是该参数字符串的副本。 String(StringBuffer buffer) //分配一个新的字符串,它包含字符串缓冲区参数中当前包含的字符序列。 String(StringBuilder builder) //分配一个新的字符串,它包含字符串生成器参数中当前包含的字符序列。
两种实例化方式