zoukankan      html  css  js  c++  java
  • Java中Class和单例类的作用与类成员的理解

    Java中Class类的作用与深入理解

        在程序运行期间,Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识。这个信息跟踪着每个对象所属的类。JVM利用运行时信息选择相应的方法执行。而保存这些信息的类称为Class。可能容易产生混淆,容易想到class。不过二者没什么关系,class不过是描述类的一个关键字。而Class却是保存着运行时信息的类。

           它能做什么?Class类可以帮助我们在程序运行时分析类,说白了就是获取类中的值。可能瞬间就想到了反射,没错!Class一般就是和反射配套使用的,因为我们向Class提供一个类或一个类的类名,Class就可以提供我们很多信息,比如属性/方法/修饰符/构造器/类名等等。然后我们就可以进一步进行反射。不过,还是先来简单了解下Class类的内容和使用方式吧!

    获取Class对象的三种方式(实例采用Person类)

    方式1:通过Object类的getObject()方法   

    Person p = new Person();
    Class c = p.getClass();

    方式2: 通过 类名.class 获取到字节码文件对象(任意数据类型都具备一个class静态属性,看上去要比第一种方式简单)。

    Class c2 = Person.class

    方式3: 通过Class类中的方法(将类名作为字符串传递给Class类中的静态方法forName即可)。  

    Class c3 = Class.forName("Person")

    注意:第三种和前两种的区别

    前两种你必须明确Person类型.

    后面是指定这种类型的字符串就行.这种扩展更强.我不需要知道类名.我只提供字符串,按照配置文件加载就可以了

    代码演示:

    public class ReflectDemo {
     public static void main(String[] args) throws ClassNotFoundException {
      //通过Object类的getObject()方法   
      Person p = new Person();
      Class c1 = p.getClass();
      System.out.println(c1);
        
      //类名.class 获取到字节码文件对象
      Class c2 =Person.class;
      System.out.println(c2);
        
      //通过Class类中的方法forName()
      Class c3 = Class.forName("cn.shiqi.demo1.Person");
      System.out.println(c3);
     }
    }
    class Person{
      
    }

    类成员的理解     

      类成员是属于整个类的,而不是属于对象的。因此创建一个对象时,只会为实例变量分配内存,而不会为类成员变量分配内存,类成员变量是在类初始化时分配的内存(执行main()方法之前),所以当类变量初始化以后,实例变量很可能还没有分配内存,因此类成员是不能访问实例变量的。
    Java中对象可以访问类成员变量(很多语言是不允许对象访问类变量的,只能访问实例变量),一般都是通过类来访问对象。

    public class NullAccessStatic
    {
       private static void test()
       {
          System.out.println("static修饰的类方法");
       }
       public static void main(String[] args)
       {
          // 定义一个NullAccessStatic变量,其值为null
          NullAccessStatic nas = null;
          //使用null对象调用所属类的类方法   
          //下面代码一切正常,可以使用空对象访问类成员,进一步说明类成员是属于类的,其并不在对应实例中   
          nas.test();
       }
    }
    //注意:如果一个null对象访问实例成员,将会引发NullPointException异常,
    //因为null表明该实例根本不存在,既然实例不存在,它的实例成员也就不存在。

    如下所示:

    public class Main {
         public static int str1=1;//类成员
         int b=2;//实例成员
        public static void main(String[] args) {
           // System.out.println("Hello World!");
    
            /*String str2 = new String("str")+new String("01");
            str2.intern();//从常量池中找,如果有直接返回该引用
            String str1 = "str01";
            System.out.println(str2 == str1);*/
    
           Main a=null;//表明实例根本不存在,既然实例不存在,那么他的实例变量和方法自然也不存在
            // Main a=new Main();
            System.out.println(a.str1);
            System.out.println(a.b);//空指针异常
        }
    }

    2 单例类
    大部分时候把类的构造器访问控制权限都定义为public,允许任何类自由创建该类的对象。但在某些时候,允许其他类自由创建该类对象没有任何意义,还可能造成系统性能下降(因为频繁的创建对象,且回收对象会带来系统开销问题),这是就需要引入单例类了。如果一个类始终只能创建一个类,则这个类就被称为单例类。
    要实现单例类需要做哪些处理:

    将类的构造器隐藏起来,用private,但又需要创建一个对象,就需要提供一个public方法,用于创建该对象,且该方法必须使用static修饰(因为调用该方法之前还不存在对象,因此调用该方法的只能是类)
    除此之外,还需要缓存已经创建好的对象,否则无法知道曾经是否创建过对象,也就无法保证只创建一个对象。为此该类需要提供一个成员变量来保存曾经创建过的对象,因为该成员变量需要被上面的方法调用,故该成员变量不许用static修饰。 

    class Singleton
    {
       ////使用一个类成员变量来缓存曾经创建过的实例   
       private static Singleton instance;
       //对构造器使用private修饰,隐藏该构造器   
       private Singleton(){}//只能本类访问
        // 提供一个静态方法,用于返回Singleton实例
       //该方法可以加入自定义控制,保证指残生一个Singleton对象
       public static Singleton getInstance()
       {
          // 如果instance为null,则表明不曾创建Singleton对象      
          //如果instance不为null,则表明已经创建过Singleton对象
          // 将不会创建新的实例 
          if (instance == null)
          {
            // 创建一个Singleton对象,将其缓存起来           
            instance = new Singleton();
          }
          return instance;
       }
    }
    public class SingletonTest
    {
       public static void main(String[] args)
       {
          //创建Singleton对象不能通过构造器      
          //只能通过getInstance方法来得到实例      
          Singleton s1 = Singleton.getInstance();
          Singleton s2 = Singleton.getInstance();
          System.out.println(s1 == s2); //将输出true
       }
    }
    Java半颗糖
  • 相关阅读:
    编译安装Nginx和php搭建KodExplorer网盘
    mysql二进制安装及基础操作
    Apache环境下搭建KodExplorer网盘
    编译安装Apache httpd和php搭建KodExplorer网盘
    KodExplorer介绍
    Nginx反向代理、负载均衡及日志
    Nginx include和Nginx指令的使用
    Nginx auto_index和auth_basic
    [译]在 64bit 环境中执行32 bit的SSIS包
    [译]SSIS 通过环境变量配置数据源连接参数
  • 原文地址:https://www.cnblogs.com/2019wxw/p/10926269.html
Copyright © 2011-2022 走看看