Java Class对象详解
要怎样在java里来使用一个类,首先必须先把类的.class字节码文件加载进来,然后再进行连接对该类里的域分配内存,最后再调用构造器,如果该类有基类的话,会先去调用基类的构造器,总的来说,分为以下三个步骤。
1.根据环境变量找到并加载.class文件
2.为该类的非编译时常量分配内存
3.调用该类的构造器
java里的所有类都有一个Class对象,通过这个Class对象我们能够获取此类的各种信息。
当某个字节码文件被JVM加载的时候,Class对象就被创建。
Class类没有构造方法,是内部的一个defineClass方法来创建此对象的,此对象与被加载的字节码文件的类的类型相对应。
其实在java里包括基本数据类型(int short long byte float double boolean char),也包括了void
System.out.println(int.class.getName());
System.out.println(char.class.getName());
System.out.println(short.class.getName());
System.out.println(long.class.getName());
System.out.println(byte.class.getName());
System.out.println(float.class.getName());
System.out.println(double.class.getName());
System.out.println(boolean.class.getName());
System.out.println(void.class.getName());
都有与之对应的class对象,同类型的类型也共享一个class对象。也包括了数组,所有同类型同维度的数组也共享一个class对象。
public class Main {
public static void main(String[] args) {
System.out.println(char[].class.getName());//[C
System.out.println(char[][].class.getName());//[[C
}
}
class的forName方法
同时class里有一个static的方法forName,可以让我们显示的来把一个类的.class文件加载至JVM虚拟机。
static Class< ? > forName(String className)
public class Main {
public static void main(String[] args) throws Exception{
Class a = Class.forName("A");
}
}
class A{
void print(){
System.out.println("hello world");
}
}
该方法返回的是一个Class对象,这个Class对象也可以添加泛型。
这样的话我们就获得一个与A类型对应的Class对象。
但是这时编译器会强制的让我们抛出或者捕获这个异常,所以我们需要将它捕获或者抛出。
接下来我们还能重载一个A类的private的构造器(注:默认的构造器是隐式的static,我们重载之后就不再是static),但是我们仍然能获取它的class对象,因为调用构造器是在最后一步,而我们这里只是加载.class文件。
public class Main {
public static void main(String[] args) throws ClassNotFoundException {
Class a = Class.forName("A");
}
}
class A{
private A(){
}
void print(){
System.out.println("hello world");
}
}
这段代码是毫无错误的
但是直到现在我们都还不能通过Class.forName来操作一个类,因为它只是简单的加载而已,但是没关系Class类还有一个newInstance方法,这个方法能帮助我们创建一个class类的实例,我们只需显示的转换一下类型即可操作A类.
public class Main {
public static void main(String[] args) throws Exception {
A a = (A)Class.forName("A").newInstance();
a.print();
}
}
class A{
void print(){
System.out.println("hello world");
}
}
这时,其实我们得到的就是一个A类型的实例了。
但是如果我们这时把A的构造方法声明为private呢?
public class Main {
public static void main(String[] args) throws Exception {
A a = (A)Class.forName("A").newInstance();
a.print();
}
}
class A{
private A(){
}
void print(){
System.out.println("hello world");
}
}
编译器是仍然不会报错的,但是如果我们执行这段代码就会发现会抛出一个异常,因为这是在运行时加载的,所以编译器是无法察觉的。这也是相当危险的,所以一般情况下我们都会遵守用new来创建对象。
既然class是运行时对象,那么对于final static 声明的域也是毫无作用的了,这么说的原因是用final static声明的域是不需要动态的来分配内存的,因为它是一个编译时常量。
到现在我们大概明白了class的含义和运用,那它和.class有什么联系呢。
其实每个类也有一个.class的常量,我们称为类字面常量,这个常量能够返回该类的class对象,也能通过newIstance创建实例来操作。
运用类字面常量的好处就在于不用去抛出或者捕获异常,所犯的错误在编译时就能查找出来。
public class Main {
public static void main(String[] args) throws Exception {
A a = (A)A.class.newInstance();
a.print();
}
}
class A{
void print(){
System.out.println("hello world");
}
}
封装类的TYPE
这里以boolean类型来说明这个问题
System.out.println(boolean.class == Boolean.TYPE);//true
所以我们得出基本类型的.class 和 封装类的TYPE是等价的。
Java Class对象详解的更多相关文章
- Java 字符串格式化详解
Java 字符串格式化详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. 在 Java 的 String 类中,可以使用 format() 方法 ...
- Java 序列化Serializable详解
Java 序列化Serializable详解(附详细例子) Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化Serialization(序列化)是一种将对象以一连 ...
- mvc-servlet---ServletConfig与ServletContext对象详解(转载)
ServletConfig与ServletContext对象详解 一.ServletConfig对象 在Servlet的配置文件中,可以使用一个或多个<init-param>标签为s ...
- JavaWeb学习----JSP内置对象详解
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- Java String类详解
Java String类详解 Java字符串类(java.lang.String)是Java中使用最多的类,也是最为特殊的一个类,很多时候,我们对它既熟悉又陌生. 类结构: public final ...
- 最新java数组的详解
java中HashMap详解 http://alex09.iteye.com/blog/539545 总结: 1.就像引用类型的数组一样,当我们把 Java 对象放入数组之时,并不是真正的把 Java ...
- JAVA IO 类库详解
JAVA IO类库详解 一.InputStream类 1.表示字节输入流的所有类的超类,是一个抽象类. 2.类的方法 方法 参数 功能详述 InputStream 构造方法 available 如果用 ...
- dom对象详解--document对象(二)
dom对象详解--style对象 style对象 style对象和document对象下的集合对象styleSheets有关系,styleSheets是文档中所有style对象的集合,这里讲解的 ...
- 转:Java HashMap实现详解
Java HashMap实现详解 转:http://beyond99.blog.51cto.com/1469451/429789 1. HashMap概述: HashMap是基于哈希表的M ...
随机推荐
- annot refer to a non-final variable * inside an inner class defined in a different method"错误解析
在使用Java局部内部类或者匿名内部类时,若该类调用了所在方法的局部变量,则该局部变量必须使用final关键字来修饰,否则将会出现编译错误“Cannot refer to a non-final va ...
- Create MSSQL Procedure
代码: CREATE PROCEDURE [dbo].[sp_UpdateCouponCount] AS GO
- 【C++ STL】List
1.结构 list使用一个double linked list(双向链表)来管理元素. 2. list 能力 list内部结构和vector或deque截然不同,所以与他们的区别: list不支持随机 ...
- 不使用Tomcat,手写简单的web服务
背景: 公司使用的YDB提供了http的查询数据库服务,直接通过url传入sql语句查询数据-_-||.ydb的使用参照:https://www.cnblogs.com/hd-zg/p/7115112 ...
- Redis 键值数据类型及基本操作
到目前为止,Redis 支持的键值数据类型如下: 字符串(String) 哈希(Map) 列表(list) 集合(sets) 有序集合(sorted sets) 1. String 字符串类型 s ...
- Item27--优先考虑泛型方法
类型推导:发生在以下三个地方.1.Java编译器根据泛型方法传入的参数,推导出具体的类型.2.Java编译器,根据泛型构造器传入的类型来推导出实际要构造的实例类型.3.Java编译器根据表达式的目标类 ...
- 【BZOJ4880】排名的战争 [暴力]
排名的战争 Time Limit: 8 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 小Q是一名出色的质检员,他负责质检 ...
- 「6月雅礼集训 2017 Day5」吃干饭
[题目大意] 询问[L,R]中选若干个数异或起来得到的答案集合大小.多组数据. 对于50%的数据,$R - L \leq 10^4$ 对于100%的数据,$R - L \leq 10^{18}, T ...
- UOJ#204 【APIO2016】Boat
Time Limit: 70 Sec Memory Limit: 256 MBSubmit: 559 Solved: 248 Description 在首尔城中,汉江横贯东西.在汉江的北岸,从西向 ...
- 【BZOJ】3971 [WF2013]Матрёшка
[算法]区间DP [题解] 参考写法:BZOJ 3971 Матрёшка 解题报告 第二个DP可以预处理mex优化到O(nM+n2),不过我懒…… 第一个DP有另一种写法:不预处理,在一个n2取出来 ...