[改善Java代码]注意Class类的特殊性
Java语言是先把Java源文件编译成后缀为class的字节码文件,然后再通过ClassLoader机制把这些类文件加载到内存中,最后生成实例执行的,这是Java处理的基本机制,但加载到内存中的数据是如何描述一个类的呢?
比如在Dog.class文件中定义了的是一个Dog类,那它在内存中是如何展现的呢?
Java使用一个元类(MetaClass)来描述加载到内存中的类数据,这就是Class类,它是一个描述类的类对象,比如Dog.class文件加载到内存中后就是一个Class实例对象描述.
因为Class是一个类种类,也就预示着它有很多特殊的地方:
1.无构造函数.Java中的类一般都有构造函数,用于创建实例对象,但是Class类却没有构造函数,不能实例化,Class对象是在加载类时由Java虚拟机通过调用类加载器中的defineClass方法自动构造的.
2.可以描述基本类型.虽然8个基本类型在JVM中并不是一个对象,它们一般存在于栈内存中,但是Class类仍然可以描述它们,例如可以使用int.class标识int类型的类对象.
3.其对象都是单例模式.一个Class的实例对象描述一个类,并且只描述一个类,反过来也成立,一个类只有一个Class实例对象,如下代码返回的结果都为true:
public class Client {
public static void main(String[] args) throws Exception {
//类的属性class所引用的对象与实例对象的getClass返回值相同
String.class.equals(new String().getClass());
"ABC".getClass().equals(String.class);
//class实例对象不区分泛型
ArrayList.class.equals(new ArrayList<String>().getClass());
}
}
Class类是Java的反射入口,只有在获得一个类的描述对象后才能动态的加载,调用,一般获得一个Class对象有三种途径:
1.类属性方式,如String.class.
2.对象的getClass()方法,如new String().getClass().
3.forName()方法加载,如Class.forName("java.lang.String");
获得了Class对象之后,就可以通过getAnnotation()获得注解,通过getMethods()获得方法,通过getConstructors()获得构造函数等,这为后续的反射代码铺平了道路.
[改善Java代码]注意Class类的特殊性的更多相关文章
- [改善Java代码]让工具类不可实例化
建议42: 让工具类不可实例化 Java项目中使用的工具类非常多,比如JDK自己的工具类java.lang.Math.java.util.Collections等都是我们经常用到的.工具类的方法和属性 ...
- [改善Java代码]使用匿名类的构造函数
建议39: 使用匿名类的构造函数 阅读如下代码,看看是否可以编译: public class Client { public static void main(String[] args) { Lis ...
- [改善Java代码]使用package-info类为包服务
建议50: 使用package-info类为包服务 Java中有一个特殊的类:package-info类,它是专门为本包服务的,为什么说它特殊呢?主要体现在3个方面: (1)它不能随便被创建 在一般的 ...
- [改善Java代码]对字符串排序 持一种宽容的心态
在Java中一涉及到中文处理就会冒出很多的问题来,其中的排序也是一个让人头疼的问题,看代码: import java.util.Arrays; public class Client { public ...
- [改善Java代码]使用静态内部类提高封装性
建议38: 使用静态内部类提高封装性 Java中的嵌套类(Nested Class)分为两种:静态内部类(也叫静态嵌套类,Static Nested Class)和内部类(Inner Class).内 ...
- [改善Java代码]使用构造块精炼程序
建议36: 使用构造代码块精炼程序 什么叫代码块(Code Block)?用大括号把多行代码封装在一起,形成一个独立的数据体,实现特定算法的代码集合即为代码块,一般来说代码块是不能单独运行的,必须要有 ...
- [改善Java代码]易变业务使用脚本语言编写
建议16: 易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP.Ruby.Groovy.JavaScript等,这些“入侵者”都有一个共同特征:全是同一类语言—脚本语言,它们 ...
- [改善Java代码]使用forName动态加载类文件
动态加载(Dynamic Loading)是指在程序运行时加载需要的类库文件,对Java程序来说,一般情况下,一个类文件在启动时或首次初始化时会被加载到内存中,而反射则可以在运行时再决定是否需要加载一 ...
- [改善Java代码]建议40:匿名类的构造函数很特殊
建议40: 匿名类的构造函数很特殊 在上一个建议中我们讲到匿名类虽然没有名字,但可以有一个初始化块来充当构造函数,那这个构造函数是否就和普通的构造函数完全一样呢?我们来看一个例子,设计一个计算器,进行 ...
随机推荐
- Hibernate配置文件——hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuratio ...
- JavaScript——以简单的方式理解闭包
闭包,在一开始接触JavaScript的时候就听说过.首先明确一点,它理解起来确实不复杂,而且它也非常好用.那我们去理解闭包之前,要有什么基础呢?我个人认为最重要的便是作用域(lexical scop ...
- XML学习笔记(1)--XML概述
XML基本概念 XML—extensible Markup Language(可扩展标记语言) XML最基本的三个概念 1)XML语言---描述事物本身(可扩展) 2)XSL语言---展现事物表现形式 ...
- codeforces 624A Save Luke(水题)
A. Save Luke time limit per test 1 second memory limit per test 256 megabytes input standard input o ...
- Educational Codeforces Round 14 D. Swaps in Permutation (并查集orDFS)
题目链接:http://codeforces.com/problemset/problem/691/D 给你n个数,各不相同,范围是1到n.然后是m行数a和b,表示下标为a的数和下标为b的数可以交换无 ...
- Educational Codeforces Round 13 D. Iterated Linear Function (矩阵快速幂)
题目链接:http://codeforces.com/problemset/problem/678/D 简单的矩阵快速幂模版题 矩阵是这样的: #include <bits/stdc++.h&g ...
- Java学习笔记(三):数组
数组声明 java语言中,数组是一种最简单的复合数据类型.数组是有序数据的集合,数组中的每个元素具有相同的数据类型,可以用一个统一的数组名和下标来唯一地确定数组中的元素. int arr1[]; in ...
- eclipse scons 使用指南
http://sconsolidator.com/projects/sconsolidator/wiki/Getting_Started Add SCons support to an existin ...
- 【M6】区别increment/decrement操作符的前置(prefix)和后置(postfix)形式
1.考虑++(--的情况是一样的),前置是累加然后取出,后置是取出然后累加. 2.重载方法根据形参表的不同区分,问题来了,前置和后置形式都没有形参,因此没法区分.怎么办? 对于后置增加一个形参int, ...
- Codeforces Round #331 (Div. 2) B. Wilbur and Array 水题
B. Wilbur and Array Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/596/p ...