本站已关停,现有内容仅作科研等非赢利用途使用。特此声明。
查看: 879|回复: 0
打印 上一主题 下一主题

Android菜鸟饭团#Java中文学习#第十六课 活动笔记

[复制链接]
跳转到指定楼层
1#
发表于 2015-5-7 12:12:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 likuilin 于 2015-5-8 21:24 编辑

Android菜鸟饭团#Java中文学习#第十六课 活动笔记
Object类:
1、J2SE5.0 JDK  Source Code下载目录:http://java.sun.com/javase/downloads/index.jsp
2、里面有JDK提供的包报下面有哪些个类,类里面有哪些个方法。
3、 Object类是所有java类的根基类,如果在类的声明中未使用extends关键字指明其基类,则默认基类为object类。
4、 所有的类都把object当成他的父类。
5、 getClass反射机制:拿到的是比自己编译好的那个class文件。
to String方法:
  • object类中定义有 public String to String()方法,其返回值是String类型,是当前对象的有关信息。
  • 在进行String与其他类型数据的连接操作时(如:System。Out。println(“info”+person)),将自动调用该对象类的 to String()方法。
  • 可以根据需要在用户自定义类型中重写to String()方法。
  • toString的好处是在碰到“println”之类的输出方法时会自动调用,不用显式打出来
解释hash码:
根据这个编码可以确定它独一无二的对象所在的位置。
equals方法:()
对象转型(casting)
面向对象的核心机制:多态/动态绑定()/迟绑定
优点:可扩展
三个必要条件:1、要有继承2、要有重写3、父类引用指向子类对象
注意(易错点):
1:classpath中的路径中不能出现同名的类
2:重写方法名必须和原方法名一模一样(注意大小写,最好直接复制)
3.指向同一对象返回true。
4.使用 instanceof操作符 比较是否是同一个对象的引用。
instanceof是Java的一个二元操作符,和==,>,<是同一类东东。由于它是由字母组成的,所以也是Java的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回boolean类型的数据。
注意:
这种做法通常被认为是没有好好利用面向对象中的多态性。其实功能要求用方法重载完全可以实现,这是面向对象变成应有的做法,避免回到结构化编程模式。
java 对象转型小结
分类: java 知识点2013-11-07 10:00 398人阅读 评论(0) 收藏 举报
一.对象的向上转型, 将子类的对象赋值给父类的引用:
Student s = new Student();
Person p = s; //向上转型
1.以上:
a)Person p = s; //向上转型
b)Person p 是父类的引用。
c)s 是子类的对象。
d) Person是sdutent的父类。
2.实例
a)通过继承关系的向上转型:
class Person{
    int age;
    String name;
    public void intorduce(){
        System.out.println("Person intorduce" + age + "name : = "+name);
     }
}
class Student extends Person{
     String address;
  public void study(){
         System.out.println("Student study");  
  }
     public void intorduce(){
       super.intorduce();
      System.out.println("Student address:=" + address);
  }
}
  class Test{
     public static void main(String args[]){
          Student s  = new Student();
          Person person = s;
   
           person.name = "zhangsan";
           person.age = 20;
          //person.address = "address";  //不能调用子类的函数
          person.intorduce(); //指向student类里面的introduce()方法。
        //p.study();  //不能调用子类的方法
      }
}
b)通过接口方式实现的向上转型
interface Person{
    public void introduce(  int age, String name );
}
class Student implements Person{
     String address;
    public void study(){
         System.out.println("Student study");  
    }
     public void introduce(int age, String name){
           System.out.println("Student introduce name:=" + name  +  " age : =" + age);  
      }
}
class Test{
      public static void main(String args[]){
            Person person = new Student();
        //   person.address = "address"; //子类特有的成员变量,向上转型之后会被遗失
          // person.study();  //子类特有方法,向上转型之后会被遗失。
            person.intorduce(20, "张三");
     }
}
3. 对对象的引用的话,需要注意:
1)一个引用能够调用那些成员(变量和函数),取决于这个引用的类型
2)一个引用调用的哪一个方法,取决于这个引用所指向的对象。
4.向上转型,可以在继承关系和接口关系中实现。
5.向上转型, 需要注意的是
  1)向上转型时,子类会遗失除去与父类对象共有的成员方法之外的其他方法。  
   2)向上转型时,子类会遗失除去与父类对象共有的成员变量之外的其他变量。
6.向上转型的好处。
看上面的代码,
    public static void doIntorduce(Person person, int age, String name) {
        person.intorduce(age, name);
    }
这里以父类为参数,调有时用子类作为参数,就是利用了向上转型。这样使代码变得简洁。不然的话,
如果doIntorduce以子类对象为参数,则有多少个子类就需要写多少个函数。这也体现了JAVA的抽象编程思想。
二.对象的向下转型, 将父类的对象赋值给子类的引用:
1.
   Student s1 = new Student();
   Person p = s1;  //向上转型
   Student s2 = (Student) p;  //向下转型
   先把一个对象向上转型,然后在把这个对象强制转换成要转换的类型。
2.实例
class Person{
    int age;
    String name;
    public void intorduce(){
         System.out.println("Person intorduce" + age + "name : = "+name);
    }
}
class Student extends Person{
     String address;
  public void study(){
         System.out.println("Student study");  
  }
     public void intorduce(){
       super.intorduce();
      System.out.println("Student address:=" + address);
  }
}
  class Test{
     public static void main(String args[]){
          Student s  = new Student();
          Person p = s;
   
          //Person p = new Sdutent();
          //向下转型
         Student s = (sdutent)p;
     }
}
类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。
java中Object是所有java类(包括自定义类)的父类。
Object的出现多用在多态上,目的就是使编写的程序有更大的通用性。
例子:
public class 动物类{
     .......
}
public class 猫类 extends 动物类{
    public string 叫声;
     .......
}
public class 狗类 extends 动物类{  
    public string 叫声;
    ........
}
这里,猫类和狗类都是动物类的子类
现在我们有一个类,这个类有一个方法,要求打印猫的叫声
public class 猫叫声类{
      public void jiao(猫类 mao){          //这里有一个猫类对象作为参数
            System.out.println(mao.叫声);//这样就可以获得猫类的叫声属性
      }
}

现在我们有一个类,这个类有一个方法,要求打印狗的叫声
public class 狗叫声类{
      public void jiao(狗类 gou){          //这里有一个狗类对象作为参数
            System.out.println(gou.叫声);//这样就可以获得狗类的叫声属性
      }
}

看到这里,是不是发现点什么问题了。这两个类几乎是完全相同的,就是jiao这个方法的参数不同,分别是猫和狗。那我们有没有什么办法,使这个类中的方法适合这两种情况呢,你是猫,我就打印猫的叫声,你是狗我就打印狗的叫声,这样不就方便多了吗?
这个就是父类对象的好处了。
public class 叫声类{
      public void jiao(动物类 dongwu){          //这里有一个动物类对象作为参数
            System.out.println(dongwu.叫声);//这样就可以获得具体类的叫声属性
      }                                                             //这地方有一个多态的性质,你相应的
}                                                                         //看这节内容
这个类写完,如果你穿过来的参数是一个狗类,大舅打印狗的叫声,如果你穿过来的是一个猫类,他就打印猫的叫声。
现在你应该明白,父类引用其实就是为了程序更加通用,这里举得是我们自定义的一个类。
object是所有类的父类,其思想和这个例子完全一样,
2.toString
用System.out.println()输出一个对象的时候,java默认调用对象的toString()方法
一般你要覆盖这个方法,这样根据覆盖逻辑你就可以输出自己的对象
比如你定义一个类User,有id,name属性,你直接输出一个user对象的话
System.out.println(user),得到的只是
全限定名@地址首地址
如果你在User类里面覆盖这个toString方法的话就能输出你要的
比如
public String toString(){
   return "user name is:"+this.name+";"+"user id is:"+this.id;
}
这样你输出一个user对象就是
User user = new User(1,"zhangshan");
System.out.println(user);
得到:user name is :zhangshan;user id is: 1;
3.equals
java中的数据类型,可分为两类:
1.基本数据类型,也称原始数据类型。byte,short,char,int,long,float,double,boolean
  他们之间的比较,应用双等号(==),比较的是他们的值。
2.复合数据类型(类)
  当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。 JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地 址,但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
  对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是基于他们在内存中的存放位置的地址值的,因为Object的equals方法也是用双等号(==)进行比较的,所以比较后的结果跟双等号(==)的结果相同。
1 public class TestString {
2  public static void main(String[] args) {
3 String s1 = "Monday";
4 String s2 = "Monday";
5 if (s1 == s2)
6 {
7 System.out.println("s1 == s2");}
8 else{
9 System.out.println("s1 != s2");}
10 }
11 }
编译并运行程序,输出:s1 == s2说明:s1 与 s2 引用同一个 String 对象 -- "Monday"!
2.再稍微改动一下程序,会有更奇怪的发现:
public class TestString {
public static void main(String[] args) {
String s1 = "Monday";
String s2 = new String("Monday");
if (s1 == s2)
{System.out.println("s1 == s2");}
else
{System.out.println("s1 != s2");}
if (s1.equals(s2)) {System.out.println("s1 equals s2");}
else{
System.out.println("s1 not equals s2");}
}
}

我们将s2用new操作符创建
程序输出:
s1 != s2
s1 equals s2
说明:s1 s2分别引用了两个"Monday"String对象

3. 字符串缓冲池
原来,程序在运行的时候会创建一个字符串缓冲池当使用 s2 = "Monday" 这样的表达是创建字符串的时候,程序首先会在这个String缓冲池中寻找相同值的对象,在第一个程序中,s1先被放到了池中,所以在s2被创建的时候,程序找到了具有相同值的 s1
将s2引用s1所引用的对象"Monday"
第二段程序中,使用了 new 操作符,他明白的告诉程序:"我要一个新的!不要旧的!"于是一个新的"Monday"Sting对象被创建在内存中。他们的值相同,但是位置不同,一个在池中游泳一个在岸边休息。哎呀,真是资源浪费,明明是一样的非要分开做什么呢?

4.再次更改程序:
public class TestString {
public static void main(String[] args) {
String s1 = "Monday";
String s2 = new String("Monday");
s2 = s2.intern();
if (s1 == s2)
{System.out.println("s1 == s2");}
else
{System.out.println("s1 != s2");}
if (s1.equals(s2)) {System.out.println("s1 equals s2");}
else{
System.out.println("s1 not equals s2");}
}
}

这次加入:s2 = s2.intern();
程序输出:
s1 == s2
s1 equals s2
原 来,(java.lang.String的intern()方法"abc".intern()方法的返回值还是字符串"abc",表面上看起来好像这个方 法没什么用处。但实际上,它做了个小动作:检查字符串池里是否存在"abc"这么一个字符串,如果存在,就返回池里的字符串;如果不存在,该方法会 把"abc"添加到字符串池中,然后再返回它的引用。
4.对象转型
一.对象的向上转型, 将子类的对象赋值给父类的引用:
Student s = new Student();
Person p = s; //向上转型
1.以上:
a)Person p = s; //向上转型
b)Person p 是父类的引用。
c)s 是子类的对象。
d) Person是sdutent的父类。

2.实例
a)通过继承关系的向上转型:
class Person{
    int age;
    String name;

    public void intorduce(){
        System.out.println("Person intorduce" + age + "name : = "+name);
     }
}

class Student extends Person{
     String address;
  
  public void study(){
         System.out.println("Student study");  
  }
     public void intorduce(){
       super.intorduce();
      System.out.println("Student address:=" + address);
  }
}

  class Test{
     public static void main(String args[]){
          Student s  = new Student();
          Person person = s;
   
           person.name = "zhangsan";
           person.age = 20;
          //person.address = "address";  //不能调用子类的函数
          person.intorduce(); //指向student类里面的introduce()方法。
        //p.study();  //不能调用子类的方法
      }
}
b)通过接口方式实现的向上转型
interface Person{
    public void introduce(  int age, String name );
}
class Student implements Person{
     String address;
  
    public void study(){
         System.out.println("Student study");  
    }
     public void introduce(int age, String name){
           System.out.println("Student introduce name:=" + name  +  " age : =" + age);  
      }
}
class Test{
      public static void main(String args[]){
            Person person = new Student();
        //   person.address = "address"; //子类特有的成员变量,向上转型之后会被遗失
          // person.study();  //子类特有方法,向上转型之后会被遗失。
            person.intorduce(20, "张三");
     }
}


3. 对对象的引用的话,需要注意:
1)一个引用能够调用那些成员(变量和函数),取决于这个引用的类型
2)一个引用调用的哪一个方法,取决于这个引用所指向的对象。
4.向上转型,可以在继承关系和接口关系中实现。
5.向上转型, 需要注意的是
  1)向上转型时,子类会遗失除去与父类对象共有的成员方法之外的其他方法。  
   2)向上转型时,子类会遗失除去与父类对象共有的成员变量之外的其他变量。
6.向上转型的好处。
看上面的代码,
    public static void doIntorduce(Person person, int age, String name) {
        person.intorduce(age, name);
    }
这里以父类为参数,调有时用子类作为参数,就是利用了向上转型。这样使代码变得简洁。不然的话,
如果doIntorduce以子类对象为参数,则有多少个子类就需要写多少个函数。这也体现了JAVA的抽象编程思想。

二.对象的向下转型, 将父类的对象赋值给子类的引用:
1.
   Student s1 = new Student();
   Person p = s1;  //向上转型
   Student s2 = (Student) p;  //向下转型
   先把一个对象向上转型,然后在把这个对象强制转换成要转换的类型。
2.实例
class Person{
    int age;
    String name;

    public void intorduce(){
         System.out.println("Person intorduce" + age + "name : = "+name);
    }
}

class Student extends Person{
     String address;
  
  public void study(){
         System.out.println("Student study");  
  }
     public void intorduce(){
       super.intorduce();
      System.out.println("Student address:=" + address);
  }
}

  class Test{
     public static void main(String args[]){
          Student s  = new Student();
          Person p = s;
   
          //Person p = new Sdutent();
          //向下转型
         Student s = (sdutent)p;
     }
}
一、概述:
       Object类是所有Java类的祖先。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。
在不明确给出超类的情况下,Java会自动把Object作为要定义类的超类。
      可以使用类型为Object的变量指向任意类型的对象。
      Object类有一个默认构造方法pubilc Object(),在构造子类实例时,都会先调用这个默认构造方法。
      Object类的变量只能用作各种值的通用持有者。要对他们进行任何专门的操作,都需要知道它们的原始类型并进行类型转换。例如:
      Object obj = new MyObject();
      MyObject x = (MyObject)obj;
二、API预览
    Object()
    默认构造方法
    clone()
    创建并返回此对象的一个副本。
    equals(Object obj)
    指示某个其他对象是否与此对象“相等”。
    finalize()
    当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
    getClass()
    返回一个对象的运行时类。
    hashCode()
    返回该对象的哈希码值。
    notify()
    唤醒在此对象监视器上等待的单个线程。
    notifyAll()
    唤醒在此对象监视器上等待的所有线程。
    toString()
    返回该对象的字符串表示。
    wait()
    导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。
    wait(long timeout)
    导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量。
    wait(long timeout, int nanos)
    导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量。
三、方法使用说明
1、equals()方法:用于测试某个对象是否同另一个对象相等。它在Object类中的实现是判断两个对象是否指向同一块内存区域。这中测试用处不大,因为即使内容相同的对象,内存区域也是不同的。如果想测试对象是否相等,就需要覆盖此方法,进行更有意义的比较。例如
class Employee{
... //此例子来自《java核心技术》卷一
    public boolean equals(Object otherObj){
        //快速测试是否是同一个对象
        if(this == otherObj) return true;
        //如果显式参数为null,必须返回false
        if(otherObj == null) reutrn false;
        //如果类不匹配,就不可能相等
        if(getClass() != otherObj.getClass()) return false;
        
        //现在已经知道otherObj是个非空的Employee对象
        Employee other = (Employee)otherObj;
        //测试所有的字段是否相等
        return name.equals(other.name)
            && salary == other.salary
            && hireDay.equals(other.hireDay);
    }
}
Java语言规范要求equals方法具有下面的特点:
自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
对于任何非空引用值 x,x.equals(null) 都应返回 false。
从这里看出,上面的例子是Java规范的equals方法的标准实现,推荐用上面例子的写法实现类的equals方法。
2、toString():返回该对象的字符串表示。Object类中的toString()方法会打印出类名和对象的内存位置。几乎每个类都会覆盖该方法,以便打印对该对象当前状态的表示。大多数(非全部)toString()方法都遵循如下格式:类名[字段名=值,字段名=值...],当然,子类应该定义自己的toString()方法。例如:
public String toString(){
    reurn "Employee[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]";
}
toString()方法是非常重要的调试工具,很多标准类库中的类都定义了toString()方法,以便程序员获得有用的调试信息。
四、来自SUN公司的java.long.Object类的API文档,网上有chm中文版的,很好找。为了查阅方便,我从SUN公司的JavaDoc站点上复制出来了Object类的API文档。
java.lang
类 Object
java.lang.Object
public class Object
类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。
从以下版本开始:
JDK1.0
另请参见:
构造方法摘要
Object()
           
方法摘要
protected  Object
clone()
          创建并返回此对象的一个副本。
boolean
equals(Object obj)
          指示某个其他对象是否与此对象“相等”。
protected  void
finalize()
          当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
Class<? extendsObject>
getClass()
          返回一个对象的运行时类。
int
hashCode()
          返回该对象的哈希码值。
void
notify()
          唤醒在此对象监视器上等待的单个线程。
void
notifyAll()
          唤醒在此对象监视器上等待的所有线程。
String
toString()
          返回该对象的字符串表示。
void
wait()
          导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。
void
wait(long timeout)
          导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量。
void
wait(long timeout, int nanos)
          导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量。
构造方法详细信息
Object
public Object()
方法详细信息
getClass
public final Class<? extends Object> getClass()
返回一个对象的运行时类。该 Class 对象是由所表示类的 static synchronized 方法锁定的对象。
返回:
表示该对象的运行时类的 java.lang.Class 对象。此结果属于类型 Class<? extends X>,其中 X 表示清除表达式中的静态类型,该表达式调用 getClass。

hashCode
public int hashCode()
返回该对象的哈希码值。支持该方法是为哈希表提供一些优点,例如,java.util.Hashtable 提供的哈希表。
hashCode 的常规协定是:
  • 在 Java 应用程序执行期间,在同一对象上多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是对象上 equals 比较中所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
  • 如果根据 equals(Object) 方法,两个对象是相等的,那么在两个对象中的每个对象上调用 hashCode 方法都必须生成相同的整数结果。
  • 以下情况不 是必需的:如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么在两个对象中的任一对象上调用 hashCode 方法必定会生成不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同整数结果可以提高哈希表的性能。
实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)
返回:
此对象的一个哈希码值。
另请参见:

equals
public boolean equals(Object obj)
指示某个其他对象是否与此对象“相等”。
equals 方法在非空对象引用上实现相等关系:
  • 自反性:对于任何非空引用值 xx.equals(x) 都应返回 true
  • 对称性:对于任何非空引用值 xy,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true
  • 传递性:对于任何非空引用值 xyz,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么x.equals(z) 应返回 true
  • 一致性:对于任何非空引用值 xy,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上equals 比较中所用的信息没有被修改。
  • 对于任何非空引用值 xx.equals(null) 都应返回 false
Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。
注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
参数:
obj - 要与之比较的引用对象。
返回:
如果此对象与 obj 参数相同,则返回 true;否则返回 false。
另请参见:

clone
protected Object clone()
                throws CloneNotSupportedException
创建并返回此对象的一个副本。“副本”的准确含义可能依赖于对象的类。一般来说,对于任何对象 x,如果表达式:
x.clone() != x
是正确的,则表达式:
x.clone().getClass() == x.getClass()
将为 true,但这些不是绝对条件。一般情况下是:
x.clone().equals(x)
将为 true,但这不是绝对条件。
按照惯例,返回的对象应该通过调用 super.clone 获得。如果一个类及其所有的超类(Object 除外)都遵守此约定,则 x.clone().getClass() == x.getClass()。
按照惯例,此方法返回的对象应该独立于该对象(正被克隆的对象)。要获得此独立性,在 super.clone 返回对象之前,有必要对该对象的一个或多个字段进行修改。这通常意味着要复制包含正在被克隆对象的内部“深层结构”的所有可变对象,并使用对副本的引用替换对这些对象的引用。如果一个类只包含基本字段或对不变对象的引用,那么通常不需要修改 super.clone 返回的对象中的字段。
Object 类的 clone 方法执行特定的克隆操作。首先,如果此对象的类不能实现接口 Cloneable,则会抛出CloneNotSupportedException。注意:所有的数组都被视为实现接口 Cloneable。否则,此方法会创建此对象的类的一个新实例,并像通过分配那样,严格使用此对象相应字段的内容初始化该对象的所有字段;这些字段的内容没有被自我克隆。所以,此方法执行的是该对象的“浅表复制”,而不“深层复制”操作。
Object 类本身不实现接口 Cloneable,所以在类为 Object 的对象上调用 clone 方法将会导致在运行时抛出异常。
返回:
此实例的一个克隆。
抛出:
CloneNotSupportedException - 如果对象的类不支持 Cloneable 接口,则重写 clone 方法的子类也会抛出此异常,以指示无法克隆某个实例。
另请参见:

toString
public String toString()
返回该对象的字符串表示。通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂。建议所有子类都重写此方法。
Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于:
getClass().getName() + '@' + Integer.toHexString(hashCode())
返回:
该对象的字符串表示形式。

notify
public final void notify()
唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。
直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争;例如,唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。
此方法只应由作为此对象监视器的所有者的线程来调用。通过以下三种方法之一,线程可以成为此对象监视器的所有者:
  • 通过执行此对象的同步 (Sychronized) 实例方法。
  • 通过执行在此对象上进行同步的 synchronized 语句的正文。
  • 对于 Class 类型的对象,可以通过执行该类的同步静态方法。
一次只能有一个线程拥有对象的监视器。
抛出:
IllegalMonitorStateException - 如果当前的线程不是此对象监视器的所有者。
另请参见:

notifyAll
public final void notifyAll()
唤醒在此对象监视器上等待的所有线程。线程通过调用其中一个 wait 方法,在对象的监视器上等待。
直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争;例如,唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。
此方法只应由作为此对象监视器的所有者的线程来调用。请参阅 notify 方法,了解线程能够成为监视器所有者的方法的描述。
抛出:
IllegalMonitorStateException - 如果当前的线程不是此对象监视器的所有者。
另请参见:

wait
public final void wait(long timeout)
                throws InterruptedException
导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量。
当前的线程必须拥有此对象监视器。
此方法导致当前线程(称之为 T)将其自身放置在对象的等待集中,然后放弃此对象上的所有同步要求。出于线程调度目的,线程 T 被禁用,且处于休眠状态,直到发生以下四种情况之一:
  • 其他某个线程调用此对象的 notify 方法,并且线程 T 碰巧被任选为被唤醒的线程。
  • 其他某个线程调用此对象的 notifyAll 方法。
  • 其他某个线程中断线程 T
  • 已经到达指定的实际时间。但是,如果 timeout 为零,则不考虑实际时间,该线程将一直等待,直到获得通知。
然后,从对象的等待集中删除线程 T,并重新进行线程调度。然后,该线程以常规方式与其他线程竞争,以获得在该对象上同步的权利;一旦获得对该对象的控制权,该对象上的所有其同步声明都将被还原到以前的状态 - 这就是调用 wait 方法时的情况。然后,线程 T 从 wait 方法的调用中返回。所以,从 wait 方法返回时,该对象和线程 T的同步状态与调用 wait 方法时的情况完全相同。
在没有被通知、中断或超时的情况下,线程还可以唤醒一个所谓的虚假唤醒 (spurious wakeup)。虽然这种情况在实践中很少发生,但是应用程序必须通过以下方式防止其发生,即对应该导致该线程被提醒的条件进行测试,如果不满足该条件,则继续等待。换句话说,等待应总是发生在循环中,如下面的示例:
synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout);
... // Perform action appropriate to condition
     }
(有关这一主题的更多信息,请参阅 Doug Lea 撰写的《Concurrent Programming in Java (Second Edition)》(Addison-Wesley, 2000) 中的第 3.2.3 节或 Joshua Bloch 撰写的《Effective Java Programming Language Guide》(Addison-Wesley, 2001) 中的第 50 项。
如果当前线程在等待时被其他线程中断,则会抛出 InterruptedException。在按上述形式恢复此对象的锁定状态时才会抛出此异常。
注意,由于 wait 方法将当前的线程放入了对象的等待集中,所以它只能解除此对象的锁定;可以同步当前线程的任何其他对象在线程等待时仍处于锁定状态。
此方法只应由作为此对象监视器的所有者的线程来调用。请参阅 notify 方法,了解线程能够成为监视器所有者的方法的描述。
参数:
timeout - 要等待的最长时间(以毫秒为单位)。
抛出:
IllegalArgumentException - 如果超时值为负。
IllegalMonitorStateException - 如果当前的线程不是此对象监视器的所有者。
InterruptedException - 如果在当前线程等待通知之前或者正在等待通知时,另一个线程中断了当前线程。在抛出此异常时,当前线程的中断状态 被清除。
另请参见:
wait
public final void wait(long timeout,
                       int nanos)
                throws InterruptedException
导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量。
此方法类似于一个参数的 wait 方法,但它允许更好地控制在放弃之前等待通知的时间量。用毫微秒度量的实际时间量可以通过以下公式计算出来:
1000000*timeout+nanos
在其他所有方面,此方法执行的操作与带有一个参数的 wait(long) 方法相同。需要特别指出的是,wait(0, 0) 与wait(0) 相同。
当前的线程必须拥有此对象监视器。该线程发布对此监视器的所有权,并等待下面两个条件之一发生:
  • 其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。
  • timeout 毫秒值与 nanos 毫微秒参数值之和指定的超时时间已用完。
然后,该线程等到重新获得对监视器的所有权后才能继续执行。
对于某一个参数的版本,实现中断和虚假唤醒是有可能的,并且此方法应始终在循环中使用:
synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout, nanos);
... // Perform action appropriate to condition
     }
此方法只应由作为此对象监视器的所有者的线程来调用。请参阅 notify 方法,了解线程能够成为监视器所有者的方法的描述。
参数:
timeout - 要等待的最长时间(以毫秒为单位)。
nanos - 额外时间(以毫微秒为单位,范围是 0-999999)。
抛出:
IllegalArgumentException - 如果超时值是负数,或者毫微秒值不在 0-999999 范围内。
IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。
InterruptedException - 如果在当前线程等待通知之前或者正在等待通知时,其他线程中断了当前线程。在抛出此异常时,当前线程的中断状态 被清除。
wait
public final void wait()
                throws InterruptedException
导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。换句话说,此方法的行为就好像它仅执行 wait(0) 调用一样。
当前的线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行。
对于某一个参数的版本,实现中断和虚假唤醒是可能的,而且此方法应始终在循环中使用:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
     }
此方法只应由作为此对象监视器的所有者的线程来调用。请参阅 notify 方法,了解线程能够成为监视器所有者的方法的描述。
抛出:
IllegalMonitorStateException - 如果当前的线程不是此对象监视器的所有者。
InterruptedException - 如果在当前线程等待通知之前或者正在等待通知时,另一个线程中断了当前线程。在抛出此异常时,当前线程的中断状态 被清除。
另请参见:
notify(), notifyAll()

finalize
protected void finalize()
                 throws Throwable
当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。子类重写 finalize 方法,以配置系统资源或执行其他清除。
finalize 的常规协定是:当 JavaTM 虚拟机已确定尚未终止的任何线程无法再通过任何方法访问此对象时,将调用此方法,除非由于准备终止的其他某个对象或类的终结操作执行了某个操作。finalize 方法可以采取任何操作,其中包括再次使此对象对其他线程可用;不过,finalize 的主要目的是在不可撤消地丢弃对象之前执行清除操作。例如,表示输入/输出连接的对象的 finalize 方法可执行显式 I/O 事务,以便在永久丢弃对象之前中断连接。
Object 类的 finalize 方法执行非特殊性操作;它仅执行一些常规返回。Object 的子类可以重写此定义。
Java 编程语言不保证哪个线程将调用某个给定对象的 finalize 方法。但可以保证在调用 finalize 时,调用 finalize 的线程将不会持有任何用户可见的同步锁定。如果 finalize 方法抛出未捕获的异常,那么该异常将被忽略,并且该对象的终结操作将终止。
在启用某个对象的 finalize 方法后,将不会执行进一步操作,直到 Java 虚拟机再次确定尚未终止的任何线程无法再通过任何方法访问此对象,其中包括由准备终止的其他对象或类执行的可能操作,在执行该操作时,对象可能被丢弃。
对于任何给定对象,Java 虚拟机最多只调用一次 finalize 方法。
finalize 方法抛出的任何异常都会导致此对象的终结操作停止,但可以通过其他方法忽略它。

【书记员:李奎林】

每一个技术小白都有一个成为大神的梦想,现在Android菜鸟饭团就给你这个成就梦想的机会。我们提供最新的Android技术教学,只要你又耐心和毅力就一定会在这里有所收获。
Android菜鸟饭团南阳GDG组织发起,秉承着开放、分享、创新的原则,希望通过GDG社区的力量能够给更多的想要学习Android开发技术的小白们创造一个学习,交流,分享的环境。同往常的GDG活动一样,我们依然是任性的一个子都不要,并且还在周六的分享中提供盒饭和不定期的惊喜小礼物呦~所以快来加入我们吧,为你的大神梦想迈出第一步。
把你的个人信息和申请理由快快发送到android@chuang1.net,前来加入我们吧

ChinaGDG.com
回复

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表