甘肃住房和城乡建设厅网站首页,莱州网站建设青岛华夏商务网,深圳网站维护页面设计,网站带数据库下载ClassClass常用方法获取Class对象六种方式哪些类型有Class对象动态和静态加载类加载流程加载阶段连接阶段连接阶段-验证连接阶段-准备连接阶段-解析初始化阶段获取类结构信息Class常用方法
第一步#xff1a;创建一个实体类
public class Car {public String brand 宝…
ClassClass常用方法获取Class对象六种方式哪些类型有Class对象动态和静态加载类加载流程加载阶段连接阶段连接阶段-验证连接阶段-准备连接阶段-解析初始化阶段获取类结构信息Class常用方法
第一步创建一个实体类
public class Car {public String brand 宝马;public int price 500000;public String color 白色;Overridepublic String toString() {return Car{ brand brand \ , price price , color color \ };}
}第二步常用方法的演示
public class Class02 {public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {String classAllPath Reflection.Car;//获取到Car类 对应的 Class对象//? 表示不确定的Java类型Class? cls Class.forName(classAllPath);//输出clsSystem.out.println(cls); //显示cls对象,是哪个类的Class对象 class Reflection.CarSystem.out.println(cls.getClass());//输出cls运行类型 class java.lang.Class//得到包名System.out.println(cls.getPackage().getName());//包名//得到全类名System.out.println(cls.getName());//通过cls创建对象实例Car car (Car)cls.newInstance();System.out.println(car);//通过反射获取属性 brandField brand cls.getField(brand);System.out.println(brand.get(car));//宝马//通过反射给属性赋值brand.set(car,奔驰);System.out.println(brand.get(car));//奔驰//得到所有的属性(字段)Field[] fields cls.getFields();for(Field f:fields){System.out.println(f.getName());//名称}}
}运行结果 获取Class对象六种方式
第一种在已知一个类的全类名且该类在类的路径下可通过Class类的静态方法Class.forName()获取多用于配置文件读取全类路径加载类
public class GetClass_ {public static void main(String[] args) throws ClassNotFoundException {//1.Class.forNameString classAllPath Reflection.Car;//通过读取配置文件获取Class? cls1 Class.forName(classAllPath);}
}第二种若已知具体的类通过类的class获取该方式最为安全可靠程序性能最高
public class GetClass_ {public static void main(String[] args) throws ClassNotFoundException {//2.类名.class,应用场景:用于参数传递Class cls2 Car.class;}
}第三种若已知某个类的实例调用该实例的getClass()方法获取Class对象
public class GetClass_ {public static void main(String[] args) throws ClassNotFoundException {//3.对象.getClass(),应用场景有对象实例Car car new Car();Class cls3 car.getClass();}
}第四种通过类加载器来获取到类的Class对象
public class GetClass_ {public static void main(String[] args) throws ClassNotFoundException {//4.通过类加载器[4种]来获取到类的Class对象String classAllPath Reflection.Car;//(1)先得到类加载器 carClassLoader classLoader car.getClass().getClassLoader();//(2)通过类加载器得到Class对象Class? cls4 classLoader.loadClass(classAllPath);}
}基本数据类型按如下方式得到Class类对象
public class GetClass_ {public static void main(String[] args) throws ClassNotFoundException {ClassInteger integerClass int.class;ClassCharacter characterClass char.class;ClassBoolean booleanClass boolean.class;}
}基本数据类型对应的包装类可以通过.TYPE得到Class类对象
public class GetClass_ {public static void main(String[] args) throws ClassNotFoundException {ClassInteger type1 Integer.TYPE;ClassCharacter type2 Character.TYPE;}
}哪些类型有Class对象 1.外部类成员内部类静态内部类局部内部类匿名内部类 2.interface接口 3.数组 4.enum枚举 5.annotation注解 6.基本数据类型 7.void 动态和静态加载
反射机制是java实现动态语言的关键也就是通过反射实现类动态加载 1.静态加载编译时加载相关的类如果没有则报错依赖性太强 假设我现在在代码里面放了一个没有创建的Dog类
public class ClassLoad_ {public static void main(String[] args) {Scanner sc new Scanner(System.in);System.out.println(请输入key);String key sc.next();switch (key){case 1:Dog dog new Dog();dog.cry();break;case 2:System.out.println(ok);break;default:System.out.println(do nothing);}}
}导致在编译的时候就发生了报错虽然我们在运行的时候不一定会使用到因为new Dog()是静态加载因此必须编写Dog 2.动态加载运行时加载需要的类如果运行时不用该类即使不存在该类则不报错降低了依赖性
public class ClassLoad_ {public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {Scanner sc new Scanner(System.in);System.out.println(请输入key);String key sc.next();switch (key){case 1:break;case 2:Class cls Class.forName(Person);//加载Person类Object o cls.newInstance();Method m cls.getMethod(hi);m.invoke(o);System.out.println(ok);break;default:System.out.println(do nothing);}}
}因为反射是动态加载可以通过编译只有在运行的时候才会报错Person类是动态加载所以没有编写Person类也不会报错只有动态加载该类的时候才会报错 1.当创建对象时(new) //静态加载 2.当子类被加载时父类也加载 //静态加载 3.调用类中的静态成员时//静态加载 4.通过反射//动态加载 类加载流程 加载阶段
JVM在该阶段的主要目的是将字节码从不同的数据源可能是class文件、也可能是jar包甚至网络转化为二进制字节流加载到内存中并生成一个代表该类的java.long.Class对象
连接阶段
连接阶段-验证
目的是为了确定文件中字节流包含的信息符合当前虚拟机的要求并且不会危害安全可以考虑使用-Xverify:none参数来关闭大部分的类验证措施缩短虚拟机类加载的时间
连接阶段-准备
JVM会在该阶段对静态变量分配内存默认初始化(对应数据类型的默认初始值如0、0L、null、false等)。这些变量所使用的内存都将在方法区中进行分配常量和静态变量不一样因为一旦赋值就不变它直接就是它对应的值
连接阶段-解析
虚拟机将常量池的符号引用替换为直接引用的过程中在编译的过程中因为没有实际的内存地址所以只能用符号的方法来记录当加载好之后用地址来替换
初始化阶段
到初始化阶段才真正开始执行类中定义的java程序代码,此阶段是执行()方法过程()方法是由编译器按语句在源文件中出现的顺序依次自动收集类中的所有静态变量的赋值动作和静态代码块中的语句并进行合并 示例代码: public class ClassLoad03 {public static void main(String[] args) {//1.加载B类并生成B的class对象//2.连接 num 0//3.初始化阶段// 依次自动收集类中的所有静态变量的赋值动作和静态代码快的语句/*
* clinit(){
* System.out.println(B 静态代码快被执行);
* num 300;
*
* 合并num100}*/new B(); System.out.println(B.num);}
}
class B{static {System.out.println(B 静态代码快被执行);num 300;}static int num 100;public B(){System.out.println(B() 构造器被执行 num);}
}运行结果 如果直接使用类的静态属性也会导致类的加载 注 虚拟机保证一个类的()方法在多线程环境中被正确地加锁、同步如果多个线程同时去初始化一个类那么只会有一个线程去执行这个类的()方法其他线程都需要阻塞等待直到线程执行()方法完毕 获取类结构信息 public class ReflectionUtils {public static void main(String[] args) throws ClassNotFoundException {api_01();}//第一组方法APIpublic static void api_01() throws ClassNotFoundException {//得到Class对象Class? personCls Class.forName(Reflection.com.hspedu.classload.Person);//获取全类名System.out.println(personCls.getName());//获取简单类名System.out.println(personCls.getSimpleName());//获取所有public修饰的属性包含本类及父类Field[] fields personCls.getFields();for (Field field : fields) {System.out.println(本类及父类属性field.getName());}//获取本类中所有属性Field[] declaredFields personCls.getDeclaredFields();for (Field declaredField : declaredFields) {System.out.println(本类中所有的属性declaredField.getName());}//获取所有public修饰的方法包含本类以及父类Method[] methods personCls.getMethods();for (Method method : methods) {System.out.println(本类以及父类的方法method.getName());}//获取本类所有的方法Method[] declaredMethods personCls.getDeclaredMethods();for (Method declaredMethod : declaredMethods) {System.out.println(本类所有方法declaredMethod.getName());}//获取所有public修饰的构造器包含本类Constructor?[] constructors personCls.getConstructors();for (Constructor? constructor : constructors) {System.out.println(本类以及父类的构造器 constructor.getName());}//获取本类所有的构造器Constructor?[] declaredConstructors personCls.getDeclaredConstructors();for (Constructor? declaredConstructor : declaredConstructors) {System.out.println(本类所有的构造器declaredConstructor.getName());}//以Package形式返回包信息System.out.println(personCls.getPackage());//以Class形式返回父类信息System.out.println(父类的class对象personCls.getSuperclass());//以Class[]形式返回接口信息Class?[] interfaces personCls.getInterfaces();for (Class? anInterface : interfaces) {System.out.println(接口信息anInterface.getName());}//返回注解信息Annotation[] annotations personCls.getAnnotations();for (Annotation annotation : annotations) {System.out.println(注解信息annotation);}}
}
interface IA{}
interface IB{}
class A{public String hobby;public void hi(){}public A(){}
}
Deprecatedclass Person extends A implements IA,IB{public Person(){}public Person(String s){ }private Person(String name,int age){}//属性public String name;protected int age;String job;private double sal;//方法public void m1(){}protected void m2(){}void m3(){}private void m4(){}}public class ReflectionUtils {public static void main(String[] args) throws ClassNotFoundException {api_02();}public static void api_02() throws ClassNotFoundException {//得到Class对象Class? personCls Class.forName(Reflection.com.hspedu.classload.Person);//获取本类所有属性Field[] declaredFields personCls.getDeclaredFields();for (Field declaredField : declaredFields) {System.out.println(本类中的所有属性declaredField.getName() 该属性的修饰符值declaredField.getModifiers() 该属性的类型declaredField.getType());}}
}
interface IA{}
interface IB{}
class A{public String hobby;public void hi(){}public A(){}
}
Deprecatedclass Person extends A implements IA,IB{public Person(){}public Person(String s){ }private Person(String name,int age){}//属性public String name;protected static int age;String job;private double sal;//方法public void m1(){}protected void m2(){}void m3(){}private void m4(){}}