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中Class和单例类的作用与类成员的理解的更多相关文章

  1. java中安全的单例与不安全的单例

    java中安全的单例与不安全的单例 1.内部静态类(安全的) public class Singleton { private static class SingletonHolder{ privat ...

  2. java 中的懒汉单例和饿汉单例模式

    //-------------------------------------------------------------饿汉模式--开始----------------------------- ...

  3. Java中的懒汉式单例与饿汉式单例实例详解

    懒汉式单例:线程非安全,当被调用的时候才创建实例,效率较高 public class LazySingleton { private static LazySingleton lazySingleto ...

  4. Java学习笔记之---单例模型

    Java学习笔记之---单例模型 单例模型分为:饿汉式,懒汉式 (一)要点 1.某个类只能有一个实例 2.必须自行创建实例 3.必须自行向整个系统提供这个实例 (二)实现 1.只提供私有的构造方法 2 ...

  5. OC中两种单例实现方式

    OC中两种单例实现方式 写在前面 前两天探索了一下C++ 的单例,领悟深刻了许多.今天来看看OC中的单例又是怎么回事.查看相关资料,发现在OC中一般有两种实现单例的方式,一种方式是跟C++ 中类似的常 ...

  6. Java中设计模式之单例设计模式-1

    单例作用 1 节省内存 2 可以避免多种状态导致状态冲突 单例的创建步骤 1 私有化构造方法 2 私有化声明的属性 3 getInstance 4 方法需要静态 单例分类 1.懒汉式 2.饿汉式 两种 ...

  7. Java中创建操作文件和文件夹的工具类

    Java中创建操作文件和文件夹的工具类 FileUtils.java import java.io.BufferedInputStream; import java.io.BufferedOutput ...

  8. Java中带包(创建及引用)的类的编译

    Java中带包(创建及引用)的类的编译与调试 java源程序的编译大家都知道,也就是cmd中到源文件所在目录下javac **.java即可,当程序中有包声明还能简简单单的直接javac **.jav ...

  9. JAVA的设计模式之单例设计模式

    1.确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例. 1)理论 Java Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在. 使用Singl ...

随机推荐

  1. RHEL 6.6配置网易CentOS镜像的yum源小结

       之前没有使用过网易CentOS镜像的yum源,最近由于需要,遂在一台测试服务器验证.测试了一下如何配置使用网易的Cent0S的yum源.此文仅仅是笔记性质,参考了网上大量资料(文末"参 ...

  2. PyCharm设置完自动上传,却不会自动上传任何内容

    Upload changed files automatically to the default server 选择了 Always 下面有一个提示 Default server or group ...

  3. June 01st, 2019. Week 22nd, Saturday

    It is the childlike mind that finds the kingdom. 正是你的童心帮你找到属于自己的王国. From Charles Fillmore. When we w ...

  4. Day11 - Python基础11 模块学习——optparse

    Python 有两个内建的模块用于处理命令行参数: 一个是 getopt,<Deep in python>一书中也有提到,只能简单处理 命令行参数: 另一个是 optparse,它功能强大 ...

  5. 漫长的 windows caffe编译过程 (OnlyCpu)

    在windows下 编译caffe代码. 官方推荐是vs2013 而我手头只有VS2017 .准备开始下载代码开始编译. 1 代码下载 windows版本的代码有两份,一份是官方的编译的windows ...

  6. 图解JVM垃圾内存回收算法

    图解JVM垃圾内存回收算法 这篇文章主要介绍了图解JVM垃圾内存回收算法,由于年轻代堆空间的垃圾回收会很频繁,因此其垃圾回收算法会更加重视回收效率,下面博主和大家来一起学习一下吧 前言 首先,我们要讲 ...

  7. css3中calc、vw、vh、vmin、vmax 属性的应用及兼容性详解

    一. calc()的使用什么是calc()? calc()从字面我们可以把他理解为一个函数function.其实calc是英文单词calculate(计算)的缩写,是css3的一个新增的功能,用来指定 ...

  8. vue中\$refs、\$emit、$on的使用场景

    1.$emit的使用场景 子组件调用父组件的方法并传递数据注意:子组件标签中的时间也不区分大小写要用“-”隔开 子组件: <template> <button @click=&quo ...

  9. spring cloud 2.x版本 Sleuth+Zipkin分布式链路追踪

    前言 本文采用Spring cloud本文为2.1.8RELEASE,version=Greenwich.SR3 本文基于前两篇文章eureka-server.eureka-client.eureka ...

  10. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 3

    18.3  PDO的安装 PDO随PHP 5.1版本发行,在PHP 5的PECL扩展中也可以使用.PDO需要PHP 5版本核心面向对象特性的支持,所以它无法在之前的PHP版本中运行.无论如何,在配置P ...