Java中的Object类和Class类

版权声明:转载请注明出处 : https://blog.csdn.net/coder_what/article/details/89501706

Copyright©Stonee

在Java中,无论是类还是接口,它们在JVM的内存逻辑模型中都会存在Super和Class指针,分别指向根类(Object类)和反射类(Class类)
在这一篇blog中会了解到很多常用方法,建议大家看api

1. 位置和内容

  • Object类和Class类都位于 java.lang. 包中,使用时均无需导入
  • 我们可以在jdk或者IDE甚至是官方文档中找到,当然,也可以利用reflect类中的方法写个小程序来找到他们的内容(一会有讨论)
public class java.lang.Object
{
  public java.lang.Object();

  protected void finalize();
  public final native void wait(long);
  public final void wait(long, int);
  public final void wait();
  public boolean equals(java.lang.Object);
  public java.lang.String toString();
  public native int hashCode();
  public final native java.lang.Class getClass();
  protected native java.lang.Object clone();
  public final native void notify();
  public final native void notifyAll();
  private static native void registerNatives();
}

关于class的就不再详细列出

2. Object类

Object类是每个类的始祖,Java中的任何一个类都是由Object类扩展而来,但不用写class a extends Object,无论是否指出,Object都被认为是此类的直接超类或间接超类。所以任何类都可以调用Object类中方法

基本操作
    1. 使用Object的变量引用各种类型的方法:Object obj = new A();
    1. 同时,当一个函数的形参是 object 的话,就说明可以传递object的子类,即任意一种类,具体可以参考我的另一篇博客,Java中用Object实现任意参数
    1. 通过强制类型转换来实现子类的具体操作: A a = (A) obj;但是需要注意,这种向下转型极有可能出错:

如下

Object obj = new A();
A aa = (A) obj;     //正确

Object obj = new B();
A ab = (A) obj;     //错误

相信大家可以看到,向下转型的条件必须是父类指向转型类的实例

常用方法

在平时编写子类的时候,经常要重写Object中的几个方法,如下:

  • public boolean equals(Object obj)

底层的实现过程为:

public boolean equals(Object obj) {   
    
    return (this == obj);
}

检测两个对象是否具有相通的引用,其中“==”比较的是地址值。下面是一个重写的例子:

class a {
    private int a;
    public a( int a){
        this.a = a;
    }
    public boolean equals(a obj){
        return this.a == obj.a;
    }
}
  • public native int hashCode();

在Java应用程序执行期间,无论何时在同一个对象上多次调用它,hashCode方法都必须始终返回相同的整数,前提是不修改对象上等号比较中使用的信息。从应用程序的一次执行到同一应用程序的另一次执行,此整数不必保持一致。
如果根据equals(Object)方法,两个对象是相等的,那么在每个对象上调用hashCode方法必须产生相同的整数结果。
但是并没有强制要求如果equals()判断两个对象不相等,那么它们的hashCode()方法就应该返回不同的值。

  • public String toString()

底层实现为:

public String toString() {   
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

Object中的toString返回的是:包名+类名+@+对象hashCode的16进制。所以当我们需要将派生类中进行字符串转换时,也需要重写toString方法

  • public final native Class<?> getClass();

取得该类已经被实例化了的对象的该类的引用,这个引用指向的是Class类的对象

3. Class类

Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识,即所谓的RTTI。这项信息纪录了每个对象所属的类。虚拟机通常使用运行时类型信息选准正确方法去执行,用来保存这些类型信息的类是Class类。Class类封装一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建。

在这里插入图片描述

  • 注意Class和class
  • 类没有公共构造函数。相反,当类装入器调用某个defineClass方法并传递类文件的字节时, 类对象由Java虚拟机自动构造
获得Class类对象的几种方法

假设 a 为一个类对象,则获得a的类对象:

  • Class c = a.getClass()
  • Class c = Class.forName(a) 但是由于传入的a可能不是类实例,所以此处应提供一个异常处理器,否则会抛出checkedexception异常
  • Class c = int.class; 注意,int需要先自动装箱,使用这种办法生成Class类对象时,不会使JVM自动加载该类(如Integer类)。而其他办法会使得JVM初始化该类。
使用Class类的对象来生成目标类的实例
  • 动态创建类实例
    Class c = Class.forName(a); 
    Object aInstance=obj.newInstance();

4. 附:通过反射类查找类中具体的字段和方法的java程序

package chapter05;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner;

/**
 * This program uses reflection to print all features of a class
 * @version 1.0 2019-04-7
 * @author stonee(http://www.stonee.club)
 */

public class ReflectionTest {
    public static void main(String [] args){

        //read class name from command line args or user input

        int flag = 1;
        String name;    //class name
        Scanner input = new Scanner(System.in);
        while(flag == 1){
            if (args.length > 0)    //from command line args
                name = args[0];
            else{   //from user input
                System.out.println("Enter class name (e.g. java.util.Date) : ");
                name = input.next();
            }

            try {
                //print class name and superClass name

                Class c1 = Class.forName(name);     //get class
                Class superC1 = c1.getSuperclass();     //get superClass

                String modifiers = Modifier.toString(c1.getModifiers());    //get the "public" to string

                if (modifiers.length() > 0)
                    System.out.print(modifiers + " ");  //print the "public"

                System.out.print("class " + name);  //print the class name

                if (superC1 != null && superC1 != Object.class)
                    System.out.print(" extends " + superC1.getName());  //print the superClass if have

                System.out.print("\n{\n");  //print "{"

                printConstructors(c1);
                System.out.println();
                printMethods(c1);
                System.out.println();
                printField(c1);
                System.out.println("}");

            }
            catch (ClassNotFoundException e){
                e.printStackTrace();
            }

            //System.exit(0);
            System.out.println("Do you wanna go on this program ?(1 or 0)");
            flag = input.nextInt();
        }
    }

    /**
     * prints all constructors of a class
     * @param c1 a class
     */
    private static void printConstructors(Class c1){

        Constructor [] constructors = c1.getDeclaredConstructors(); //返回这个类或接口所有共有方法,不包括继承

        for (Constructor c:
             constructors) {

            String name = c.getName();
            System.out.print("  ");

            String modifiers = Modifier.toString(c.getModifiers());    //get the "public" to string

            if (modifiers.length() > 0)
                System.out.print(modifiers + " ");  //print the "public"

            System.out.print(name + "(");

            // print parameter types
            Class [] paramTypes = c.getParameterTypes();
            for (int i = 0; i < paramTypes.length; i++){
                if (i > 0)
                    System.out.print(", ");
                System.out.print(paramTypes[i].getName());
            }
            System.out.println(");");
        }

    }

    private static void printMethods(Class c1){
        Method[] methods = c1.getDeclaredMethods();

        for (Method m:
             methods) {

            Class retType = m.getReturnType();  //得到返回值
            String name = m.getName();

            System.out.print("  ");

            //print modifiers, return type and method name
            String modifiers = Modifier.toString(m.getModifiers());    //get the "public" to string

            if (modifiers.length() > 0)
                System.out.print(modifiers + " ");  //print the "public"

            System.out.print(retType.getName() + " " + name + "("); //打印方法的返回值和方法名

            //print the parameter types
            Class [] paramTypes = m.getParameterTypes();
            for (int i = 0; i < paramTypes.length; i++){
                if (i > 0)
                    System.out.print(", ");
                System.out.print(paramTypes[i].getName());
            }
            System.out.println(");");

        }
    }

    private static void printField(Class c1) {
        Field[] fields = c1.getDeclaredFields();

        for (Field f :
                fields) {

            Class fType = f.getType();  //得到返回值
            String name = f.getName();

            System.out.print("  ");

            //print modifiers, return type and method name
            String modifiers = Modifier.toString(f.getModifiers());    //get the "public" to string

            if (modifiers.length() > 0)
                System.out.print(modifiers + " ");  //print the "public"

            System.out.print(fType.getName() + " " + name + ";" ); //打印方法的返回值和方法名
            System.out.println();

        }
    }
}


猜你喜欢

转载自blog.csdn.net/coder_what/article/details/89501706