java 反射基础_JAVA 反射基础-Go语言中文社区

1. 先认识两个类

Object:超类,所有的类全是继承于他

Class类:同样继承于Object类,该类主要存储各个类的原信息。

2. 反射作用

简单来说,就是在只知道该类的类名的情况下,可以用该类 实例化一个对象,并且操作该类的各种方法和数据。

3.反射的简单方法

3.1先定义一个Group类

package baobao;

public class Group {

public String username;

public int age;

public String setusername(String username)

{

return this.username = username;

}

public String getusername()

{

return this.username;

}

public int setage(int age)

{

return this.age = age;

}

public int getage()

{

return this.age;

}

}3.2定义一个测试类,里面写测试方法

3.2.1 生成Class对象的几个方法

@Test

public void test()

{

Group group = new Group();

Class> demo = null;

//直接输出实例化对象

System.out.println(group);

//方法1:类.class,生成一个Class类的对象,存储Group类的各种元信息

System.out.println("类.class :"+Group.class);

//方法2:对象.getClass,生成一个Class类的对象,存储Group类的各种元信息

System.out.println("对象.getClass() :"+group.getClass());

//方法3:Class.forName("类的url").生成一个Class类的对象,存储Group类的各种元信息

try {

demo = Class.forName("baobao.Group");

System.out.println("Class.forName("类的url") :"+group.getClass());

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

输出的结果:

baobao.Group@ad021c3

类.class :                           class baobao.Group

对象.getClass() :                 class baobao.Group

Class.forName("类的url") :class baobao.Group

3.2.2Class对象可以干什么,简单说一下,该段代码不能跑

Class> demo = null;

Object object1 = null;

Object object2 = null;

Object object3 = null;

try {

// 先创建一个关于baobao.Group的Class对象

demo = Class.forName("baobao.Group");

// 创建了Class对象后可以干什么呢?简单说下

// 1.获取属性(权限、类型、名称)

demo.getFields(); // 获取所有属性

demo.getFields()[0].getType();// 获取第一个属性的类型,这是一个Class对象哦

demo.getField("");// 获取指定属性

demo.getField("").getType();// 获取指性的类型,也是一个Class对象

// 2.获取所有构造函数

Constructor[] xuni = demo.getConstructors();

// 3.带参构造函数实例化对象

object1 = xuni[0].newInstance();

object2 = xuni[1].newInstance(10, 10, 10, 10);

// 4.无参构造实例化对象

object3 = demo.newInstance();

// 5.使用实例对象的方法

Class[] str = { demo.getField("").getType(),demo.getField("").getType() };

Method method =demo.getMethod("方法名", str);// getMethod("方法名",{String.class,int.class,各种类型的Class对象});

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}3.2.3  示例:使用反射方法给username赋值并取出值

简单代码如下

@Test

public void testfanshe() {

Class> demo = null;

Object object = null;

try {

demo = Class.forName("baobao.Group");

object = demo.newInstance();

System.out.println(String.class);

System.out.println(object.getClass().getField("username").getType());

Class>[] str = { object.getClass().getField("username").getType() };

Method method = demo.getMethod("setusername", str);

method.invoke(object, "姓名");

method = demo.getMethod("getusername");

System.out.println(method.invoke(object));

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

运行结果:

class java.lang.String

class java.lang.String

姓名

建议看看这篇文章,让你对反射有更新的认识。

以下是转载的内容

一、Java的反射机制每个Java程序执行前都必须经过编译、加载、连接、和初始化这几个阶段,后三个阶段如下图:其中3c25e12b69d2bc4e1e193a1c7396ff33.pngi、加载是指将编译后的java类文件(也就是.class文件)中的二进制数据读入内存,并将其放在运行时数据区的方法区内,然后再堆区创建一个Java.lang.Class对象,用来封装类在方法区的数据结构。即加载后最终得到的是Class对象,并且更加值得注意的是:该Java.lang.Class对象是单实例的,无论这个类创建了多少个对象,他的Class对象时唯一的!!!!。而加载并获取该Class对象可以通过三种途径:

Class.forName(类的全路径)、实例对象.class(属性)、实例对象getClass()。关于他们的区别将在下面讲到!!!###另外,类加载时类中的静态代码块会得到执行(详见前一篇博客:Class.forName()加载JDBC驱动)ii、在

连接和初始化阶段,其实静态变量经过了两次赋值:第一次是静态变量类型的默认值;第二次是我们真正赋给静态变量的值。iii、Java对类的使用分为两种方式:主动使用和被动使用。其中主动使用如下图:d354956261e20e6f952efaf4778aee37.png而类的初始化时机正是java程序对类的首次主动使用,除了以上6中方式,其他对类的使用都是被动使用,都不会导致类的初始化。

并且应该注意以下几个方面:74daef6e5aa10382e53a6d3dc35e3a6d.pngb5bc1fba6abd8d5bfb926c29b8f65472.png在这里可以看出;接口的两重性:可以把接口当做类(因为在接口中有静态变量时,他可以被初始化);接口就是接口,和类无关(接口中

没有构造方法,所以不能被初始化)二、Class.forName、实例对象.class(属性)、实例对象getClass()的区别1、相同点:通过这几种方式,得到的都是Java.lang.Class对象(这个是上面讲到的

类在加载时获得的最终产物)例如:package

demo;public class A{public

static void main(String[] args) throws Exception{System.out.println(A.class);//通过类.class获得Class对象A

a = new A();System.out.println(a.getClass());//通过

实例名.getClass()获得Class对象System.out.println(Class.forName("demo.A"));//通过Class.forName(全路径)获得Class对象System.out.println(".................................");System.out.println(a);//使用不同的方式创建对象System.out.println(A.class.newInstance());System.out.println(a.getClass().newInstance());System.out.println(Class.forName("demo.A").newInstance());}}结果:class demo.Aclass

demo.Aclass

demo.A(这里也可以得到一个类的Class对象是唯一的).......................................demo.A@de6ceddemo.A@c17164demo.A@1fb8ee3demo.A@61de332、区别:

1)Class cl=A.class; JVM将使用类A的类装载器,将类A装入内存(前提是:类A还没有装入内存),不对类A做类的初始化工作.返回类A的Class的对象

2)Class cl=对象引用o.getClass();返回引用o运行时真正所指的对象(因为:儿子对象的引用可能会赋给父对象的引用变量中)所属的类的Class的对象

3)Class.forName("类名"); JAVA人都知道.装入类A,并做类的初始化

附:

从JVM的角度看,我们使用关键字new创建一个类的时候,这个类可以没有被加载。但是使用Class对象的newInstance()方法的时候,就必须保证:1、这个 类已经加载;2、这个类已经连接了。而完成上面两个步骤的正是Class的静态方法forName()所完成的,这个静态方法调用了启动类加载器,即加载java API的那个加载器。现在可以看出,Class对象的newInstance()(这种用法和Java中的工厂模式有着异曲同工之妙)实际上是把new这个方式分解为两步,即首先调用Class加载方法加载某个类,然后实例化。 这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了一种降耦的手段。最后用最简单的描述来区分new关键字和newInstance()方法的区别:newInstance: 弱类型。低效率。只能调用无参构造。new: 强类型。相对高效。能调用任何public构造。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值