javase(7)_Objcet类
一、Object源代码
class Object {
private static native void registerNatives();
static {registerNatives();}
public final native Class<?> getClass();
public native int hashCode();
public boolean equals(Object obj) {return (this == obj);}
protected native Object clone() throws CloneNotSupportedException;
public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());}
public final native void notify();
public final native void notifyAll();
public final native void wait(long timeout) throws InterruptedException;
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < ) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < || nanos > ) {
throw new IllegalArgumentException("nanosecond timeout value out of range");
}
if (nanos >= || (nanos != && timeout == )) {
timeout++;
}
wait(timeout);
}
public final void wait() throws InterruptedException {wait();}
protected void finalize() throws Throwable { }
}
二、首先说下native关键字
1、什么是Native Method?
"A native method is a Java method whose implementation is provided by non-java code."
在定义一个native method时,并不提供实现体,有些像定义一个java interface,因为其实现体是由非java语言在外面实现的.
2、为什么要使用Native Method?
一些底层的任务(与操作系统和硬件相关的任务)用java实现起来不容易,或者用java时效率低,这里用到了Native方法,JVM的一部分是用C写的.
三、Objcet是所有java类的超类,也就是所有对象包括数组,都继承Objcet的11个方法.
1、getClass(),返回一个对象的运行时类,一个类加载到内存时,.class文件已经封装为一个对象,getClass()方法返回一个Class的类的对象,该类描述类的共性 (都有类名,都有构造函数等),反射中用到.
public static void main(String[] args) {
GregorianCalendar cal = new GregorianCalendar();
System.out.println("" + cal.getTime());
System.out.println("" + cal.getClass());
Integer i = new Integer();
System.out.println("" + i.getClass());
}
运行结果如下:
Fri Sep 04 11:56:03 CST 2015
class java.util.GregorianCalendar
class java.lang.Integer
2、equals(Objcet o),默认比较的对象的引用,也就内存地址,也就是说,对于任何非空引用值x和y,此方法返回true当且仅当x和y引用同一个对象(y=y的值为true).基本类型的包装类和字符串实现了equals方法,比较的是值是否相同.
1.基本类型包装类实例:
public static void main(String[] args) {
int i0 = ;
int i1 = ;
Integer i2 = ;
Integer i3 = ;
Integer i4 = ;
Integer i5 = ;
Integer i6 = new Integer(); System.out.println(i0 == i1); // true,双等号用在基本类型变量比较的是值,用在对象比较的是内存地址
System.out.println(i2 == i3); // true,常量池技术,底层享元设计模式实现
System.out.println(i4 == i5); // false
System.out.println(i2 == i6); // false,i6在堆内存中
/* System.out.println(i0.equals(i2)); //编译报错,基本类型没有继承Objcet类 */
System.out.println(i4.equals(i5)); // true,基本类型的包装类已经重写equals
System.out.println(i2.equals(i6)); // true
}
2.String类实例:
public static void main(String[] args) {
String s0 = "aa";
String s1 = "aa";
String s2 = new String("aa");
String s3 = null;
String s4 = null; System.out.println(s0 == s1); // true,常量池
System.out.println(s0 == s2); // false,s2位于堆空间
System.out.println(s0.equals(s1)); // true,String类已经重写equals
System.out.println(s0.equals(s2)); // true
/*
* System.out.println(s3.equals(s4)); //运行期报空指针异常
* System.out.println(s3==s4); //true,null也是常量
*/
}
3.常量池技术
java中的常量池技术,是为了方便快捷地创建某些对象而出现的,当需要一个对象时,就可以从池中取一个出来(如果池中没有则创建一个),则在需要重复重复创建相等变量时节省了很多时间.常量池其实也就是一个内存空间,不同于使用new关键字创建的对象所在的堆空间,java中基本类型的包装类的大部分都实现了常量池技术,这些类是Byte,Short,Integer,Long,Character,Boolean,以及特殊的常量null,两种浮点数类型的包装类则没有实现.另外Byte,Short,Integer,Long,Character这5种整型的包装类也只是在对应值小于等于127大于-128,也就是一个字节以内时才使用对象池,这也合理,毕竟一个字节以内的数使用较为频繁,再大了使用较少,这时使用常量池,反而会使效率变低.常量池底层使用享元设计模式实现.
4.享元设计模式
面向对象可以非常方便的解决一些扩展性的问题,但是在这个过程中系统务必会产生一些类或者对象,如果系统中存在对象的个数过多时,将会导致系统的性能下降.对于这样的问题解决最简单直接的办法就是减少系统中对象的个数.享元模式提供了一种解决方案,使用共享技术实现相同或者相似对象的重用.
享元模式的核心在于享元工厂类,享元工厂类的作用在于提供一个用于存储享元对象的享元池,用户需要对象时,首先从享元池中获取,如果享元池中不存在,则创建一个新的享元对象返回给用户,并在享元池中保存该新增对象.
public class FlyweightFactory {
private HashMap flyweights = new HashMap(); public Flyweight getFlyweight(String key) {
if (flyweights.containsKey(key)) {
return (Flyweight) flyweights.get(key);
} else {
Flyweight fw = new ConcreteFlyweight();
flyweights.put(key, fw);
return fw;
}
}
}
一个例子**经典:
假如我们有一个绘图的应用程序,通过它我们可以出绘制各种各样的形状、颜色的图形,通过享元模式我们就可以实现该属性的共享了.如下:
首先是形状类:Shape.java.它是抽象类,只有一个绘制图形的抽象方法.
public abstract class Shape {
public abstract void draw();
}
然后是绘制圆形的具体类.Circle.java
public class Circle extends Shape{
private String color;
public Circle(String color){
this.color = color;
}
public void draw() {
System.out.println("画了一个" + color +"的圆形");
}
}
再是享元工厂类.FlyweightFactory
public class FlyweightFactory{
static Map<String, Shape> shapes = new HashMap<String, Shape>(); public static Shape getShape(String key){
Shape shape = shapes.get(key);
//如果shape==null,表示不存在,则新建,并且保持到共享池中
if(shape == null){
shape = new Circle(key);
shapes.put(key, shape);
}
return shape;
} public static int getSum(){
return shapes.size();
}
}
最后是客户端程序:Client.java
public class Client {
public static void main(String[] args) {
Shape shape1 = FlyweightFactory.getShape("红色");
shape1.draw();
Shape shape2 = FlyweightFactory.getShape("灰色");
shape2.draw();
Shape shape3 = FlyweightFactory.getShape("绿色");
shape3.draw();
Shape shape4 = FlyweightFactory.getShape("红色");
shape4.draw();
Shape shape5 = FlyweightFactory.getShape("灰色");
shape5.draw();
Shape shape6 = FlyweightFactory.getShape("灰色");
shape6.draw();
System.out.println("一共绘制了"+FlyweightFactory.getSum()+"中颜色的圆形");
}
}
运行结果:
画了一个红色的圆形
画了一个灰色的圆形
画了一个绿色的圆形
画了一个红色的圆形
画了一个灰色的圆形
画了一个灰色的圆形
一共绘制了3种颜色的圆形
PS享元详细参见:https://github.com/Byronlee/Design-patterns/blob/master/patterns_explain/flyweight_pattern/lecture.md
3、hashCode(),此方法返回当前对象的哈希码值,是根据对象的内存地址算出的一个10进制值,基本类型包装类(Byte,Character,Short,Integer,Long)会返回当前对象的值.重写equals方法的都重写了hashCode()方法,例String类从写的hashCode,字符串内容相等,hashCode就相同,接口Collection中有hashCode和equals方法,所以所有的集合类都实现了,equals和hashCode方法,比较的都是集合的内容是否相同而不是内存地址,内容相同equsl返回true,hashCode返回的也是同一整数.具体在集合中总结.
public class Demo {
public static void main(String[] args) {
GregorianCalendar cal = new GregorianCalendar();
System.out.println(cal.hashCode());
Integer i = ;
System.out.println(i.hashCode());
String s0="ww";
String s1=new String("ww");
System.out.println(s0.hashCode()==s1.hashCode());
}
}
运行结果:
1489234018
5
true
4、toString(),返回该对象的字符串表示形式(返回类名+@+16进制内存地址值),集合,数组等都已实现该方法.
public static void main(String[] args) {
Integer i = new Integer(50);
ArrayList list = new ArrayList();
list.add(50);
list.add("Hello World");
System.out.println(list.toString());
}
运行结果:
[50,Hello Wordl]
5.多线程的函数
notify()
唤醒在此对象监视器上等待的单个线程.
void notifyAll()
唤醒在此对象监视器上等待的所有线程.
void wait()
导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法.
void wait(long timeout)
导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量.
void wait(long timeout, int nanos)
导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量.
javase(7)_Objcet类的更多相关文章
- Java匹马行天下之JavaSE核心技术——工具类
Java匹马行天之JavaSE核心技术——工具类 一.Object类 java.lang.ObjectObject类是所有类直接或间接的父类 常用的方法: toString():以字符串形式返回对象的 ...
- JavaSE 面试题: 类初始化和实例初始化等
JavaSE 面试题 类初始化和实例初始化等 class Father { private int i = test(); private static int j = method(); stati ...
- [javaSE] 反射-获取类的成员属性和构造方法
成员属性和构造方法皆为对象,通过Class对象的方法可以得到 package com.tsh.reflect; import java.lang.reflect.Constructor; import ...
- [javaSE] 反射-Class类的基本操作
获取类的名称 获取该类的方法 获取方法的返回值类型 获取方法的名称 获取方法的参数的类型 package com.tsh.reflect; import java.lang.reflect.Metho ...
- [javaSE] 反射-Class类的使用
JAVA-Reflect 专题 ①Class类的使用 ②方法的反射 ③成员变量的反射 ④构造函数的反射 ⑤java类的加载机制 Ⅰ在面向对象的世界里,万事万物皆为对象 类是对象,类是java.lang ...
- JavaSE(一) IO类层次关系和各种IO流的用法总结
今天把IO流的这一知点进行一下总结,因为在之前使用io流的时候,就只知道几个重点常用的IO类,比如FileInputStream,BufferedInputStream(缓冲流)等等,但是不知道它处于 ...
- JavaSE之Math类
下列哪个选项是正确计算42度(角度)的余弦值? double d=Math.cos(42) double d=Math.cosine(42) double d=Math.cos(Math.toRadi ...
- 06 - JavaSE之常用类
String类 String 类是不可变的字符序列,String 字符串一旦分配好就不能改变其内容和长度了.(如果使用 s1+=s2; 并不是在s1的后面开辟空间将s2拷贝其内,而是另外开辟一个空间, ...
- [javaSE] 集合工具类(Collections-sort)
java为我们提供了一个集合的工具类,方便我们对集合进行操作,里面的方法都是静态方法. Collections.sort()方法,参数:List<T>集合对象,这个对象带着泛型,是为了保证 ...
随机推荐
- Android DPAD not enabled in AVD
问题描述:打开Android的仿真器,右侧的按键部分对于上下左右键出现以下现象后果是,这些按键都没法使用,由于我是测试一个小游戏,俄罗斯方块,朋友,要是少了上下左右键,让我情何以堪,而且我试过使用键盘 ...
- numpy windows环境下载安装
由于numpy在多个平台下非常流行,以至于习惯WINDOWS环境下的用户可能找不到下载位置,更多的时候会下载到zip文件,然后需要安装编译(自然通不过) 1.http://www.scipy.org/ ...
- 升级ruby的版本
升级ruby版本,有时候安装ruby的版本过低,需要进行升级,例如安装在centos6.7安装fpm需要ruby版本在1.9以上. 1.主机环境如下: [root@test ~]# cat /etc/ ...
- Hexo搭建博客教程(2) - 博客的简单个性化配置
本章主要讲博客的个性化,譬如站点的基本配置(语言.头像.站点图标等).安装新的Hexo主题(NexT主题)以及主题的配置. 1. 修改站点配置 打开站点配置文件 ,找到: # Site title: ...
- 洛谷1537(bitset+01背包)
总数是偶数并且其一半可得即可. bitset的移位可替代原本的数组转移. #pragma comment(linker, "/STACK:1024000000,1024000000" ...
- centOS6.5 usr/src/kernels下为空
用uname -r查看内核版本为 2.6.32-431.el6.x86_64 usr/src/kernels下为空 需要执行两个安装 yum install kernel-headers yum in ...
- 学习中对input()的一些总结(raw_input()与input())
- ubuntu下lnmp添加虚拟目录没有权限
lnmp.org下载的lnmp集成环境,通过lnmp vhost tsp创建了虚拟主机目录,将此目录导入到phpstorm中时提示错误,应该时权限的问题,想通过chmod -R 777 tsp来改变t ...
- LINUX一网卡多IP设置
方法1:少量IP手动绑定(这里以绑定IP到eth0为例,其它网卡的话修改相应的文件名即可) 1.复制ifcfg-eth0的网卡配置文件并改名为ifcfg-eth0:0 [root@akinlau /] ...
- 破解MySQL和修改mysql的密码
/etc/init.d/mysql stop mysqld_safe --user=mysql --skip-grant-tables --skip-networking & mysql -u ...