JAVA中类、实例与Class对象
已同步更新至个人blog:http://dxjia.cn/2015/08/java-class-object/
类
类是面向对象编程语言的一个重要概念,它是对一项事物的抽象概括,可以包含该事物的一些属性定义,以及操作属性的方法。面向对象编程中,我们都是以类来编码。
实例
简单理解,就是new,就是对类的实例化,创建这个类对应的实际对象,类只是对事物的描述,而实例化就相当于为这个描述新开辟了一块内存,可以改变这块区域里的各种属性(成员变量),当然,也可以实例化多块区域,只是不同的对象而已。
Class
注意这里C大写了,与类概念区分开,在java里,Class是一个实实在在的类,在包 java.lang 下,有这样一个Class.java文件,它跟我们自己定义的类一样,是一个实实在在的类,Class对象就是这个Class类的实例了。在Java里,所有的类的根源都是Object类,而Class也不例外,它是继承自Object的一个特殊的类,它内部可以记录类的成员、接口等信息,也就是在Java里,Class是一个用来表示类的类。(o(∩_∩)o 有点绕啊,抓住关键一点,Class是一个实实在在的类,可以为它创建实例,也就是本文后面提到的Class对象,也看叫做Class实例)。
java提供了下面几种获取到类的Class对象的方法:
1) 利用对象实例调用getClass()方法获取该对象的Class实例;
2) 使用Class类的静态方法forName("包名+类名"),用类的名字获取一个Class实例
3)运用 类名.class 的方式来获取Class实例;
我们知道java世界是运行在JVM之上的,我们编写的类代码,在经过编译器编译之后,会为每个类生成对应的.class文件,这个就是JVM可以加载执行的字节码。运行时期间,当我们需要实例化任何一个类时,JVM会首先尝试看看在内存中是否有这个类,如果有,那么会直接创建类实例;如果没有,那么就会根据类名去加载这个类,当加载一个类,或者当加载器(class loader)的defineClass()被JVM调用,便会为这个类产生一个Class对象(一个Class类的实例),用来表达这个类,该类的所有实例都共同拥有着这个Class对象,而且是唯一的。
总结
在java里,类只是信息描述的,写明了有哪些内部属性及接口,你可以理解为是定义了一套规则;而Class对象在java里被用来对类的情况进行表述的一个实例,也就是是类的实际表征,可以理解为是对规则的图表化,这样JVM才能直观的看懂,可以看做是一个模版;而类的实例化对象,就是通过模版,开辟出的一块内存进行实际的使用。
例子:
我们通过一个例子来理解Class实例,为了说明方便,我们新建一个包名深点的类。
新建Name.java(当然,该文件要放在com\dxjia\sample的目录下)
package com.dxjia.sample;
public class Name {
static int count = 0;
static {
count++;
System.out.println("Name Class Loaded! count = [" + count + "]" );
}
public Name() {
System.out.println("Name Constructor called!");
}
}
再在根目录新建一个Test主类
import com.dxjia.sample.Name;
public class Test {
static {
Name mName;
System.out.println("Test Class loaded");
}
public static void main(String[] args) {
System.out.println("entern Test main()");
// Name.class
Class mClassPointClass;
// Class.forName("完整包名+类名")
Class mClassForName;
// new 对象后,对象.getClass()
Class mClassObjectPointClass1;
Class mClassObjectPointClass2;
try {
//测试 类名.class
mClassPointClass = Name.class;
System.out.println("mClassPointClass = " + mClassPointClass);
//测试Class.forName()
mClassForName = Class.forName("com.dxjia.sample.Name");
System.out.println("mClassForName = " + mClassForName);
//测试Object.getClass()
Name name1 = new Name();
mClassObjectPointClass1 = name1.getClass();
System.out.println("mClassObjectPointClass1 = " + mClassObjectPointClass1);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
Name name2;
System.out.println("defined one Name object");
name2 = new Name();
System.out.println("Name object instance done!");
mClassObjectPointClass2 = name2.getClass();
if (mClassForName == mClassPointClass
&& mClassPointClass == mClassObjectPointClass1
&& mClassObjectPointClass1 == mClassObjectPointClass2) {
System.out.println("all the Class object equal...");
}
}
}
分别对他们进行编译:
javac com\dxjia\sample\Name.java
javac Test.java
执行:
java Test
代码中使用了static静态代码块来进行实验,一个类的运行,JVM做会以下几件事情 1、类装载 2、链接 3、初始化 4、实例化;而初始化阶段做的事情是初始化静态变量和执行静态方法等的工作,而且永远只执行一次。
输出结果:
Test Class loaded
entern Test main()
mClassPointClass = class com.dxjia.sample.Name
Name Class Loaded! count = [1]
mClassForName = class com.dxjia.sample.Name
Name Constructor called!
mClassObjectPointClass1 = class com.dxjia.sample.Name
defined one Name object
Name Constructor called!
Name object instance done!
all the Class object equal...
通过结果可以看出在使用 类名.class获得Class实例时,并不会触发类的初始化,而 Class.forName方法就会触发,当然实例化对象肯定也是会触发的,但因为static代码块只执行一次,所以不会再有打印,最后的打印,说明一个类的Class实例只有唯一的一个。
扩展:
对于Class.forName("")方法,可以看看下面这篇文章,结合起来理解,会更清晰:理解Class.forName()
JAVA中类、实例与Class对象的更多相关文章
- java中类的初始化和对象的初始化
静态的属于全局静态区,这个部分独立存在,不管是成员还是块,都是静态的,大家地位相等,先到先得. 然后是成员初始化,这个部分在类的构造函数前初始化,因为编译器(或者设计者)可能认为构造函数调用了这个成员 ...
- Java中类,对象,方法的内存分配
Java中类,对象,方法的内存分配 以下针对引用数据类型: 在内存中,类是静态的概念,它存在于内存中的CodeSegment中. 当我们使用new关键字生成对象时,JVM根据类的代码,去堆内存中开辟一 ...
- java中类的创建及初始化过程
java中类的创建及初始化过程无外乎两种情况,其一为单类的创建及初始化,其二具有继承关系的父子类创建及初始化过程. 首先说简单的,单类的创建及初始化过程.在java中我们都知道绝大部分对象的创 ...
- Java中类的加载、连接和初始化
Java中类的加载.连接和初始化 类的加载.连接和初始化 先介绍一下JVM和类 JVM和类: 当我们调用Java命令运行某个Java程序时,该命令将会启动一个Java虚拟机进程,不管该Java程序有多 ...
- Java(四、类和对象)
Java 对象和类 Java作为一种面向对象语言.支持以下基本概念: 多态.继承.封装.抽象.类.对象.实例.方法.重载 对象 对象是类的一个实例(对象不是找个女朋友),有状态和行为.例如,一条狗是一 ...
- Java中类的继承深入剖析
在Java开发中,我们常常用到继承这一概念,可以说继承是Java这类面向对象编程语言的基石.正是有了继承这个概念,使得我们可以创建分等级层次的类.今天小编就和大家一起来深入聊聊Java语言的继承. 在 ...
- Java面向对象(一) 类和对象
一.软件开发进化史 摘自<从零开始学架构> 机器语言(1940年) 最早的软件开发使用的是“机器语言”,直接使用二进制码0和1来表示机器可以识别的指令和数据. 汇编语言(20世纪40年代) ...
- Java入门 - 语言基础 - 04.对象和类
原文地址:http://www.work100.net/training/java-object-class.html 更多教程:光束云 - 免费课程 对象和类 序号 文内章节 视频 1 概述 2 J ...
- 四、java基础-面向过程_对象_类中可出现的因素
1.面向过程和面向对象区别: 1)面向过程:开发一个应用程序.一个项目,必须先了解整个过程,了解各个步骤.模块间的因果关系,使的面向过程方式去开发程序时,代码和代码之间的关联程度是非常强.所以其中任何 ...
- JAVA RMI 实例
下面我将介绍一个完整的实例,让初学者能快速体验RMI的功用. 分为以下四个步骤 1. 创建远程接口及声明远程方法(HelloInterface.java)2. 实现远程接口及远程方法(继承Unicas ...
随机推荐
- Java入门1dayCode
public class HelloWorld { /* * 多行注释方式 * main()方法: java语言的入口方法(函数) */ public static void main(String[ ...
- Hibernate映射之OneToOne(第二篇)
这是在项目中实际遇到的一个问题,纠结了很久.一开始参考mkyong的 ,两边都写OneToOne ,后来查看了一下项目经理在原来一些模块中的写法. 学习一下: 首先是E-R图: 一个货品可以进行多次 ...
- jsp中利用response.senddirect(str)重定向,传递参数新思路
用Servlet进行请求重定向,参数传递好办,直接用request.setAttribute(str1,str2); 但是如果不用Servlet 而是直接用jsp进行转发呢? 我们首先要知道 请求 ...
- 从0开始学Swift笔记整理(三)
这是跟在上一篇博文后续内容: --Swift中相关的属性 存储属性 Swift中的属性分为存储属性和计算属性,存储属性就是Objective-C中的数据成员,计算属性不存储数据,但可以通过计算其他属性 ...
- Spring Mobile 1.1.0.RC1 和 1.0.2 发布
Spring Mobile 1.1.0.RC1 发布了,该版本包含: 支持 Firefox OS 设备的检测 修复了使用 LiteDeviceDelegatingViewResolver 处理重定向和 ...
- 使用ODP.NET查询数据参数顺序问题及莫名ORA-01722错误提示
最近由于项目需要,必须使用C#配合Oracle来进行开发,在开发的过程中,发现有些查询无法正确获取数据.例如: Select * From tabParam Where ParamCode = :Pa ...
- 【基础知识】.Net基础加强09天
委托: 1. 委托是一种数据类型,像类一样{可以声明委托变量类型} 2. deleate关键字定义委托 : public delegate void MethodDelegate();//这就是定义了 ...
- 使用 Microsoft Fakes 进行单元测试
本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 在编写单元测试时,我们会遇到不同的外部依赖项,大体上可以分为两类: 依赖于接口或抽象类 依赖于具体类 ...
- 在项目中引用GreenDroid库
1.下载GreenDroid库 首先,我们得从Git上下载这个库,我用的是git for windows下载的.先下载,安装.安装完后,打开git for windows ,直接将浏览器中GreenD ...
- Local Optimization Revisited
十年前刚入行的时候,做为一名被agile刚洗脑的新兵,觉得自己仿佛掌握了什么神兵秘器.你看,你们这里那里都是在做local optimization,你看你不懂什么叫value driven吧,你做这 ...