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 ...
随机推荐
- 本地更新代码同步至github仓库
昨晚在家里写了一个demo放到github上,然后今天晚上来公司准备搞一下,但是git pull下来在本地修改之后push不到github上,然后发现公司电脑上并没有access权限,然后想起来还没配 ...
- ZooKeeper屏障和队列的指南(七)
引言 在这个指南中,使用展示了使用ZooKeeper实现的屏障和生产-消费队列.我们分别称这些类为Barrier和Queue.这些例子假定你至少有一个运行的ZooKeeper服务. 两个原语都使用下面 ...
- [Luogu 2580] 于是他错误的点名开始了
[Luogu 2580] 于是他错误的点名开始了 不用好奇我为什么突然发水题题解- 突然觉得自己当年的幼儿园码风太幼稚,就试图把数据结构什么的用指针重写一遍- 想当年因为空间开太大而全 RE,调了一下 ...
- Golang向Templates 插入对象的值
Go对象可以插入到template中,然后把对象的值表现在template中,你可以一层层的分解这个对象,去找他的子字段,当前对象用'.'来表示,所以当当前对象是一个string的时候,你可以用{{. ...
- Item27--优先考虑泛型方法
类型推导:发生在以下三个地方.1.Java编译器根据泛型方法传入的参数,推导出具体的类型.2.Java编译器,根据泛型构造器传入的类型来推导出实际要构造的实例类型.3.Java编译器根据表达式的目标类 ...
- Bzoj1312 / POJ3155 Neerc2006 Hard Life
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 459 Solved: 114 Description 在一家公司中,人事部经理与业务部经理不和.一次 ...
- python学习笔记(一)之为什么学习python
python的特点: 跨平台 实现同一个功能是Java代码的1/5 python应用范围: 操作系统 web 3D动画 企业应用 云计算 如何学习python? 学习语法 验证例子 学会总结 课外实践
- Quartz的Properties文件解析
将可变信息放在properties文件是使配置更加灵活. 1.文档位置和加载顺序 1. StdSchedulerFactory默认加载quartz包下的quartz.properties文件,如果我们 ...
- ubuntu下定时弹窗记录工作日志
背景 记录工作日志,是一个很好的习惯,但不容易坚持,本来打算每天记录,但经常拖延,拖着拖着,有一些事情就忘记了. 等到写周报或月报的时候,才会开始翻邮件,聊天记录,各个仓库的提交log等,回忆都干了些 ...
- python实战===短信验证码的小项目
项目地址 https://www.shiyanlou.com/courses/609/labs/2007/document flask的中文文档 http://docs.jinkan.org/docs ...