一般,我们学习一个新知识,往往是最艰难的时候,因为人总是很排斥新鲜的事物,但是往往新事物有着更优秀的机制,所以还是努力学吧。学习新知识,有一下四个须知:
- 是什么
- 有什么用
- 怎么用
- 它比原有知识强在哪里
如果能把上面四个问题搞清楚,我想就应该算初步掌握了这个知识,下面言归正传,讲Class对象,这应该和jvm有点关系。
参考博客:https://www.cnblogs.com/sharpest/p/7807009.html
https://www.cnblogs.com/guohaien/p/7350331.html
1.什么是Class
java程序在运行时,Java运行时,系统一直对所有的类的对象进行所谓的运行时类型标识。这项信息记录了每个对象所属的类。虚拟机通常使用运行时类型信息选准正确方法 去执行,用来保存这些类型信息的类是Class类。虚拟机为每种类型(即每个类)创建一个独一无二的Class对象。也就是说,每个类都有一个Class对象。
即每当编写并且编译一个新类的时候就会产生一个Class对象。当程序创建第一个对类的静态成员的引用的时候,会将该类动态加载到JVM中,这个说明了类的构造起器也是一个静态方法,即使在构造器之前并没有使用static关键字。所以java程序在运行之前并没有被完全加载,各个类只在需要的时候才将该类的Class对象载入内存,该Class对象被用来创建这个类的所有对象。 运行程序时,Java虚拟机(JVM)首先检查是否 所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。
在同一个jvm中,每个类只对应一个class对象,但可以创建多个java对象(就是一个学生类可以创建多个学生)。
- Class 没有公共构造方法
这句话我的理解是一个Class类不能创建各种类的Class对象,创建Class对象只能用每个实际类调用Class的方法创建出各自的Class对象
- Class 对象是在加载类时由Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的,因此不能显式地声明一个Class对象。
这句话的“”显式”,我的理解就是不能用new创建Class对象。如:Class clazz = new Class();
- 基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也都对应一个 Class 对象。
- 每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。 一般某个类的Class对象被载入内存,它就用来创建这个类的所有对象。
2.Class类的创建
共有三种方法:
1、调用Object类的getClass()方法来得到Class对象,返回该对象的类的Class对象。
对象.getClass();
2、使用Class类的中静态forName()方法获得与字符串对应的Class对象。
Class.forName("类名"),传入类的全名。该方法还有一个作用就是若该类未被加载则加载它,他会抛出异常。
3、获取Class类型对象的第三个方法非常简单。
类名.class
3. Class常用方法
- getFields:获取public修饰的所有属性,返回一个Field数组(包括父类的)
- getDeclaredFields:获取所有属性,返回一个Field数组
- getField:传入一个参数(属性名),获取单个属性,返回一个Field对象,只能获取public修饰的
- getDeclaredField:传入一个参数(属性名),获取单个属性,返回一个Field对象
package com.classObject;
import java.lang.reflect.Field;
import java.util.Arrays;
class User {
private int id;
public String name;
public void method1() {
System.out.println("use method1");
}
private void method2() {
System.out.println("use method2");
}
}
class ClassTest {
public static void main(String[] args) throws NoSuchFieldException,
SecurityException, ClassNotFoundException {
//Class clazz = User.class;
//方法一
// User user = new User();
// Class clazz = user.getClass();
//方法二
Class clazz = Class.forName("com.classObject.User");
//方法三
Field[] fields1 = clazz.getFields();
System.out.println(Arrays.toString(fields1));
//[public java.lang.String com.classObject.User.name]
Field[] fields2 = clazz.getDeclaredFields();
System.out.println(Arrays.toString(fields2));
//[private int com.classObject.User.id, public java.lang.String com.classObject.User.name]
Field field1 = clazz.getField("name");
System.out.println(field1);
//public java.lang.String com.classObject.User.name
//Field field2 = clazz.getField("id"); // 运行时抛异常
Field field3 = clazz.getDeclaredField("id");
System.out.println(field3);
//private int com.classObject.User.id
Field field4 = clazz.getDeclaredField("name");
System.out.println(field4);
//public java.lang.String com.classObject.User.name
}
}
- getMethods:获取所有的public修饰的方法,包括父类的,返回Method数组
- getDeclaredMethods:获取所有的返回,不包括父类,返回Method数组
- getMethod:传入一个参数(方法名),返回一个Method对象,只能获取到public修饰的
- getDeclared:传入一个参数(方法名),返回一个Method对象
package com.classObject.method;
import java.lang.reflect.Method;
import java.util.Arrays;
class User {
private int id;
public String name;
public void method1() {
System.out.println("use method1");
}
private void method2() {
System.out.println("use method2");
}
}
class ClassTest {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException {
//Class clazz = User.class;
//方法一
// User user = new User();
// Class clazz = user.getClass();
//方法二
Class clazz = Class.forName("com.classObject.User");
//方法三
Method[] methods1 = clazz.getMethods();
System.out.println(Arrays.toString(methods1));
//public void com.classObject.User.method1()
Method[] methods2 = clazz.getDeclaredMethods();
System.out.println(Arrays.toString(methods2));
//[private void com.classObject.User.method2(), public void com.classObject.User.method1()]
Method method1 = clazz.getMethod("method1");
System.out.println(method1);
//public void com.classObject.User.method1()
Method method3 = clazz.getDeclaredMethod("method1");
System.out.println(method3);
//public void com.classObject.User.method1()
Method method4 = clazz.getDeclaredMethod("method2");
System.out.println(method4);
//private void com.classObject.User.method2()
}
}