zoukankan      html  css  js  c++  java
  • 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 < 0) {
                throw new IllegalArgumentException("timeout value is negative");
            }
            if (nanos < 0 || nanos > 999999) {
                throw new IllegalArgumentException("nanosecond timeout value out of range");
            }
            if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
                timeout++;
            }
            wait(timeout);
        }
        public final void wait() throws InterruptedException {wait(0);}
        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(5);
          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 = 2;
        int i1 = 2;
        Integer i2 = 2;
        Integer i3 = 2;
        Integer i4 = 128;
        Integer i5 = 128;
        Integer i6 = new Integer(2);
    
        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 = 5;
            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() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量.

      

  • 相关阅读:
    elastic-job-console
    CentOS7_安装mysql5.7
    CentOS7_开放指定端口
    CentOS7_防火墙
    Docker-CentOS7-安装
    MySQL_写锁_lock tables tableName write
    cesium 动态流动纹理
    cesium加载二维贴地的地名(本地地名数据)
    python3.6安装open AI gym环境(windows)
    python PIL打开较大的tif影像时出错-OSError: cannot identify image file Image.open
  • 原文地址:https://www.cnblogs.com/wangweiNB/p/4781441.html
Copyright © 2011-2022 走看看