我是靠谱客的博主 甜美玉米,最近开发中收集的这篇文章主要介绍Java之反射第十八天( --反射----类的加载--获取对象属性( 成员变量和方法)-- 构造方法 ),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

                                                你想获得什么样的成功 ,你愿意为这份成功付出什么?

    https://blog.csdn.net/BuddyUU/article/details/52458241   反射精讲!

1. 类的加载

    https://blog.csdn.net/zcxwww/article/details/51330327      ----网址内有具体的解析类加载

 1.  加载过程:  将.class文件加载到内存里面;

                    把编译完成的class文件,加载到方法区;

                    在堆区创建一个表示class文件的对象; ( 反射主要就是使用这一方面 );

     2. 链接

                2. 验证:      查看一下你这个类的内部结构, ( 成员变量和成员方法);

                3.准备 :     为静态成员开辟内存空间并且进行赋初始值;

                4.解析:      将虚拟机常量池中的符号引用替换成直接引用的过程; 例如c=1 将c的位置变为1;

  3.初始化: 在初始化阶段, 则是根据程序员通过程序的主管计划初始化类变量和其他资源;

 java虚拟机规范了4种情况必须立即对垒进行初始化( 加载 验证 准备 必须在此之前进行完成 )

1. 当使用new 关键字实例化对象是,当读取或者设置一个类的静态字段( 被final修饰的除外),以及调用

一个类的静态方法是(  比如构造方法就是静态方法,)如果类未初始化,则需要先进性初始化;

2. 通过反射机制对类进行调用时,如果类没有初始花化,则先需要初始化;

3.当初始化一个类是, 如果其父类没有进行初始化, 县初始化父类;

4.用户指定的执行主类( 含有main 方法的那个类 ),在虚拟机启动的时候,会先被初始化;

 除了上面这4种方式,所有引用类的方式都不会触发初始化,称为被动引用。如:通过子类引用父类的静态字段,不会导致子类  初始化;通过数组定义来引用类,不会触发此类的初始化;引用类的静态常量不会触发定义常量的类的初始化,因为常量在编  译阶段已经被放到常量池中了。

以上: 类的加载并且使用的整个过程, java的类只有在需要的时候才会被加载进来,为内存节约了很大的空间;


2. 类使用什么进行加载?

 类使用类加载器进行加载( 共三种)

      1.       根加载器;  加载java的核心类库,系统的库;

     2.        扩展加载器: ext结尾的都是扩展加载器进行加载的;

     3 .      系统加载器:  加载我们放进去的第三方类库;

3.反射:

   反射可以把一个正在运行的类( 已经加载到内存中的类)

   通过class文件的对象直接获取, 该文件中的成员变量和方法( 可以是私有权限,包括private修饰的);

4. 如何获取class文件对象, class类 共三种方式;

     1.  对象获取:  object.getClass();

    2.  类名进行获取 ;  类名.class

   3. Class的静态方法获取;  Class.forName( com.lan.Person); 括号里面是包加类名;


1.获取Class对象的三种方法展示;

/*
* Class文件对象的获取;
*/
public class 自我练习使用 {
public static void main(String[] args) throws ClassNotFoundException {
// 第一种获取方式
Person p1 = new Person();
Class<? extends Person> class1 = p1.getClass();
System.out.println(class1);
//打印结果 class com.lanou3greflect.Person
// 第二中获取方式;
Class<?> c2 = Person.class;
System.out.println(c2);
// 第三种方式 静态获取;
Class<?> c3 = Class.forName("com.lanou3greflect.Person");
System.out.println(c3);
}
}

2.获取构造方法 getConstructor( type.class,  type.class ); 利用构造方法创建对象newInstance(); 

public static void main(String[] args) throws ClassNotFoundException, Exception, Exception {
// funclass类的获取();
// 第一步: 先使用静态获取类;获取类中的构造方法,找到person类;
Class<?> c1 = Class.forName("com.lanou3greflect.Person");
// 第二步: 获取类中的构造方法; 获取到的是所有的构造方法;是个数组;
Constructor<?>[] cons = c1.getConstructors();
System.out.println(Arrays.toString(cons));
// 获取类中无参构造方法
Constructor<?> con1 = c1.getConstructor();
System.out.println(con1);
// 获取有参构造方法
Constructor<?> con2 = c1.getConstructor(String.class, int.class);
System.out.println(con2);
//通过有参构造方法进行创建对象; instance 实例的
Object newInstance = con2.newInstance("张建海",26);
System.out.println(newInstance);
}

3. 利用 Class文件对象直接进行对象的创建

// 利用class文件对象,快速创建对象; 要求( 1.构造方法必须public 修饰, 2. 类是public修饰) 3.必须提供无参构造方法
Class<?> class1 = Class.forName("com.lanou3greflect.Person");
Object newInstance = class1.newInstance();
System.out.println(newInstance);

4. 获取私有化的构造方法;


// fun2获取构造方法创建对象();
// fun3快速创建对象();
// 获取私有化构造方法 也就是private修饰的;
// 第一步 创建class对象
Class<?> forName = Class.forName("com.lanou3greflect.Person");
// 第一步: 使用获取私有方法的构造方法;
Constructor<?> constructor = forName.getDeclaredConstructor(int.class, String.class);
// 第三步 : 打开构造方法的访问权限;
constructor.setAccessible(true);
// 第四步进行赋值
Object person = constructor.newInstance(18, "胡小青");
System.out.println(person);

5. 获取成员变量getFiled() ,getDeclaredFiled(),


// 获取成员方法
// 1.获取Class.forName;
Class<?> class1 = Class.forName("com.lanou3greflect.Person");
// 获取所有的成员变量,是个数组;只能获取公开的;
Field[] fields = class1.getFields();
for (Field field : fields) {
System.out.println(field);
}
// 获取单个成员变量 NoSuchFieldException在获取私有的时候和没有这个成员变量的时候,
//Field field = class1.getField("age");
//System.out.println(field);
//获取单个私有的成员变量
Field declaredField = class1.getDeclaredField("age");
//开放访问权限
declaredField.setAccessible(true);
System.out.println(declaredField);

6.获取成员方法getMethod()  


// fun5获取成员变量();
// 第一步: 获取Class.forName
Class<?> c = Class.forName("com.lanou3greflect.Person");
// 获取 : 成员方法 获取所有的方法,包括继承过来的方法
Method[] methods = c.getMethods();
for (Method method : methods) {
System.out.println(method);
}
// 第二步 :获取单个成员方法; 有参数就填class文件;
Method method = c.getMethod("eat");
System.out.println(method);
// invoke
// 参数1表示用哪个对象, 参数2: 方法传入;
Object object = c.newInstance();
// 该方法的返回值就是调用这个方法的返回值;
Object invoke = method.invoke(object);
System.out.println(invoke + "---我是返回值");
// 调用待返回值得成员方法;和参数名
Method method2 = c.getMethod("speak", String.class);
//给object的对象的方法进行赋值;
Object invoke2 = method2.invoke(object, "中国话");
//invoke2是返回值;
System.out.println(invoke2 + "喂喂喂");
// 调用私有方法;
Method declaredMethod3 = c.getDeclaredMethod("playGame", String.class);
declaredMethod3.setAccessible(true);
Object invoke3 = declaredMethod3.invoke(object, "lol");
// 没有返回值,返回值是Null
System.out.println(invoke3);

最后

以上就是甜美玉米为你收集整理的Java之反射第十八天( --反射----类的加载--获取对象属性( 成员变量和方法)-- 构造方法 )的全部内容,希望文章能够帮你解决Java之反射第十八天( --反射----类的加载--获取对象属性( 成员变量和方法)-- 构造方法 )所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部