类的加载:
1.加载
2.链接:
验证:确保加载的类信息符合JVM规范
准备:正式为类变量(static)分配内存并设置类变量默认初始值的阶段,这些内存将都在方法去中进行分配
解析:虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程
3.初始化
执行类构造器()方法的过程。(类构造器是构造类信息的,不是构造该类对象的构造器)
虚拟机会保证一个类的()方法在多线程环境中被正确加锁和同步
import java.lang.annotation.ElementType;
import java.util.Objects;
public class Test04 {
public static void main(String[] args) {
A a = new A();
System.out.println(A.m);
}
}
/*
1.先加载到内存(方法区),会产生一个类对应的Class对象(在堆中)
2.链接,链接结束后 m = 0
3.初始化
<clinit>(){
System.out.println("静态代码")
m = 300
m = 100
}
*/
class A{
static{
System.out.println("静态代码块类加载");
m = 300;
}
static int m = 100;
public A(){
System.out.println("构造器调用");
}
}
类加载器
public class Test05 {
public static void main(String[] args) throws ClassNotFoundException{
ClassLoader classLoader = Class.forName("Test05").getClassLoader();
System.out.println(classLoader);
//JDK内置类的加载
classLoader = Class.forName("java.lang.Object").getClassLoader();
System.out.println(classLoader);
//获得系统类的path
System.out.println(System.getProperty("java.class.path"));
//双亲委派机制,为了安全性,先会搜索这个类是否在已有包中存在
}
}
获取类运行时的结构
import com.sun.xml.internal.ws.encoding.MtomCodec;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test06 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
Class c1 = Class.forName("User");
//获得类的名字
System.out.println(c1.getName());//包名 + 类名
System.out.println(c1.getSimpleName());//类名
//获得类的属性
System.out.println("====================");
Field[] fields = c1.getFields();//只能找到Public属性
fields = c1.getDeclaredFields();//找到全部的属性
for(Field field : fields){
System.out.println(field);
}
//获得指定属性的值
Field name = c1.getDeclaredField("name");
System.out.println(name);
//获得类的方法
System.out.println("==========================");
Method[] methods = c1.getMethods();//获得本类及其父类的全部public方法
for(Method method : methods){
System.out.println("正常的:" + method);
}
methods = c1.getDeclaredMethods();//获得本类的所有方法
for(Method method : methods){
System.out.println("getDeclaredMethods:" + method);
}
//获得指定方法
Method getName = c1.getMethod("getName",null);
Method setName = c1.getMethod("setName", String.class);
System.out.println(getName);
System.out.println(setName);
//获得指定的构造器
System.out.println("================================");
Constructor[] constructors = c1.getConstructors();
for(Constructor constructor : constructors){
System.out.println(constructor);
}
constructors = c1.getDeclaredConstructors();
for(Constructor constructor : constructors){
System.out.println(constructor);
}
//获得指定的构造器
Constructor constructor = c1.getConstructor(String.class,int.class,int.class);
System.out.println(constructor);
}
}
class User{
private String name;
private int age;
private int id;
public User(){
}
public User(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;
}
............//getter and setter
}
动态创建对象执行方法
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//动态的创建对象,通过反射
public class Test09 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//获取Class对象
Class c1 = Class.forName("User");
//构造一个对象
User user = (User) c1.newInstance();//本质上是调用了类的无参构造器
System.out.println(user);//若无无参构造器会报错
//通过构造器创建对象
Constructor constructor = c1.getDeclaredConstructor(String.class,int.class,int.class);
User user1 = (User)constructor.newInstance("aaa",18,20);
System.out.println(user1);
//通过反射调用普通方法
User user3 = (User)c1.newInstance();
//通过反射获取一个方法
Method setName = c1.getMethod("setName", String.class);
//invoke:激活的意思
//(对象,”方法的值“)
setName.invoke(user3,"haha");
System.out.println(user3.getName());
//通过反射操作属性
User user4 = (User)c1.newInstance();
Field name = c1.getDeclaredField("name");
//直接访问会报错,因为name为private
//可以关掉一个权限检测,true为取消检测,通过属性方法的setAccessible
name.setAccessible(true);
name.set(user4,"kkkkk");
System.out.println(user4.getName());
}
}
class User{
private String name;
private int age;
private int id;
public User(){
}
public User(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}