java field api_Java反射机制及API使用

反射简单来说,就是动态加载对象,并对对象进行剖析。在Java中的反射机制是指在运行状态中,对于任意一个类,都能够知道并获取这个类的所有属性和方法。

Java反射机制的作用:

在运行时判断任意一个对象所属的类。

在运行时判断任意一个类所具有的成员变量和方法。

在运行时任意调用一个对象的方法

在运行时构造任意一个类的对象

反射机制的优缺点是什么?

反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性。

它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它

满足我们的要求。这类操作总是慢于只直接执行相同的操作。

获取Class对象的三种方式

package com.gyl;

public class Student {

public int no;

public String sex;

private String name;

private int age;

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;

}

/*

* 构造方法

*/

Student(String str){

System.out.println("(默认)的构造方法 s = " + str);

}

//无参构造方法

public Student(){

System.out.println("调用了公有、无参构造方法执行了。。。");

}

//有一个参数的构造方法

protected Student(char name){

System.out.println("姓名:" + name);

}

//有多个参数的构造方法

public Student(String name ,int age){

System.out.println("姓名:"+name+"年龄:"+ age);//这的执行效率有问题,以后解决。

}

//私有构造方法

private Student(int age){

System.out.println("私有的构造方法 年龄:"+ age);

}

}

package com.gyl;

import java.lang.reflect.Constructor;

public class Main {

public static void main(String[] args) throws ClassNotFoundException {

Student student = new Student();

/*

* JAVA反射--获取Class对象的三种方式

*/

// 通过对象名.getClass()方法获取

Class stuClass = student.getClass();

System.out.println("stuClass is "+stuClass.getName());

// 通过类名.class方式获得

Class stuClass1 = Student.class;

System.out.println("stuClass1 is "+stuClass1.getName());

System.out.println(stuClass == stuClass1);

// 通过Class.forName()方法获得

Class stuClass2 = Class.forName("com.gyl.Student");

System.out.println("stuClass2 is "+stuClass2);

System.out.println(stuClass1 == stuClass2);

}

}

Output:

stuClass is com.gyl.Student

stuClass1 is com.gyl.Student

true

stuClass2 is class com.gyl.Student

true

在运行期间,一个类,只有一个Class对象产生。三种方式常用第三种,第一种对象都有了还要反射干什么。第二种需要导入类的包,依赖太强,不导包就抛编译错误。一般都选第三种,一个字符串可以传入也可写在配置文件中等多种方法。

反射API

获取构造方法

// 返回指定参数类型 public的构造器。

Constructor getConstructor(类>... parameterTypes)

// 返回指定参数类型的构造器(public, protected, private)。

Constructor getDeclaredConstructor(类>... parameterTypes)

// 返回所有的public类型的构造器

Constructor>[] getConstructors()

// 返回所有的构造器

Constructor>[] getDeclaredConstructors()

package com.gyl;

import java.lang.reflect.Constructor;

public class Main {

public static void main(String[] args) throws ClassNotFoundException {

// 通过Class.forName()方法获得Class对象

Class stuClass = Class.forName("com.gyl.Student");

System.out.println("************返回所有public构造方法************");

Constructor[] constructors = stuClass.getConstructors();

for (Constructor constructor : constructors) {

System.out.println(constructor);

}

/*

* Output:

* ************返回所有public构造方法************

* public com.gyl.Student()

* public com.gyl.Student(java.lang.String,int)

*/

System.out.println("************所有的构造方法(包括:私有、受保护、默认、公有)***************");

Constructor[] constructors2 = stuClass.getDeclaredConstructors();

for (Constructor constructor : constructors2) {

System.out.println(constructor);

}

/*

* Output:

* ************所有的构造方法(包括:私有、受保护、默认、公有)***************

* private com.gyl.Student(int)

* public com.gyl.Student()

* protected com.gyl.Student(char)

* public com.gyl.Student(java.lang.String,int)

* com.gyl.Student(java.lang.String)

*/

Constructor constructor;

System.out.println("************返回指定类型的 public构造器************");

try {

constructor = stuClass.getConstructor(String.class, int.class);

System.out.println(constructor);

} catch (NoSuchMethodException e) {

e.printStackTrace();

} catch (SecurityException e) {

e.printStackTrace();

}

/*

* Output:

* ************返回指定类型的 public构造器************

* public com.gyl.Student(java.lang.String,int)

*

* 如果指定参数的构造器是非public类型的 则抛出java.lang.NoSuchMethodException异常

*/

System.out.println("************返回指定类型的构造器************");

try {

constructor = stuClass.getDeclaredConstructor(int.class);

System.out.println(constructor); // char.class

} catch (NoSuchMethodException e) { // String.class, int.class

e.printStackTrace();

} catch (SecurityException e) {

e.printStackTrace();

}

/*

* Output:

* ************返回指定类型的构造器************

* public com.gyl.Student(java.lang.String,int)

* protected com.gyl.Student(char)

* private com.gyl.Student(int)

*/

}

}

获取变量

// 根据变量名获得对应的变量,访问权限不限;

Field getDeclaredField(String name)

// 获得类中所有属性变量

Field[] getDeclaredFields()

// 根据变量名获取对应public类型的属性变量

Field getField(String name)

// 获取类中所有public类型的属性变量

Field[] getFields()

package com.gyl;

import java.lang.reflect.Field;

public class Main {

public static void main(String[] args) throws ClassNotFoundException {

// 通过Class.forName()方法获得Class对象

Class stuClass = Class.forName("com.gyl.Student");

try {

Field field1 = stuClass.getField("sex");

System.out.println(field1);

Field field = stuClass.getDeclaredField("name");

System.out.println(field);

} catch (NoSuchFieldException e) {

e.printStackTrace();

} catch (SecurityException e) {

e.printStackTrace();

}

/*

* Output:

* public java.lang.String com.gyl.Student.sex

* private java.lang.String com.gyl.Student.name

* 如果使用getField方法指定了一个非public类型的属性,则抛出java.lang.NoSuchFieldException异常

*/

Field[] fields1 = stuClass.getFields();

Field[] fields = stuClass.getDeclaredFields();

System.out.println("************返回所有public属性************");

for (Field field : fields1) {

System.out.println(field);

}

/*

* Output:

* ************返回所有public属性************

* public int com.gyl.Student.no

* public java.lang.String com.gyl.Student.sex

*/

System.out.println("************返回所有属性************");

for (Field field : fields) {

System.out.println(field);

}

/*

* Output:

* ************返回所有属性************

* public int com.gyl.Student.no

* public java.lang.String com.gyl.Student.sex

* private java.lang.String com.gyl.Student.name

* private int com.gyl.Student.age

*/

}

}

获取方法

// 获取“名称是name,参数是parameterTypes”的public的函数(包括从基类继承的、从接口实现的所有public函数)

public Method getMethod(String name, Class[] parameterTypes)

// 获取全部的public的函数(包括从基类继承的、从接口实现的所有public函数)

public Method[] getMethods()

// 获取“名称是name,参数是parameterTypes”,并且是类自身声明的函数,包含public、protected和private方法。

public Method getDeclaredMethod(String name, Class[] parameterTypes)

// 获取全部的类自身声明的函数,包含public、protected和private方法。

public Method[] getDeclaredMethods()

// 如果这个类是“其它类中某个方法的内部类”,调用getEnclosingMethod()就是这个类所在的方法;若不存在,返回null。

public Method getEnclosingMethod()

package com.gyl;

import java.lang.reflect.Method;

public class Main {

public static void main(String[] args) throws ClassNotFoundException {

// 通过Class.forName()方法获得Class对象

Class stuClass = Class.forName("com.gyl.Student");

Method method;

try {

// method = stuClass.getMethod("getName");

method = stuClass.getDeclaredMethod("getAge");

System.out.println(method);

} catch (NoSuchMethodException e) {

e.printStackTrace();

} catch (SecurityException e) {

e.printStackTrace();

}

System.out.println("*********输出所有方法********");

Method[] methods = stuClass.getDeclaredMethods();

for (Method method2 : methods) {

System.out.println(method2);

}

/*

* Output:

* public int com.gyl.Student.getAge()

* *********输出所有方法********

* public java.lang.String com.gyl.Student.getName()

* public void com.gyl.Student.setName(java.lang.String)

* void com.gyl.Student.print(java.lang.String)

* public int com.gyl.Student.getAge()

* public void com.gyl.Student.setAge(int)

*/

}

}

通过反射越过泛型检查

泛型用在编译期,编译过后泛型擦除(消失掉)。所以是可以通过反射越过泛型检查的

import java.lang.reflect.Method;

import java.util.ArrayList;

/*

* 通过反射越过泛型检查

*

* 例如:有一个String泛型的集合,怎样能向这个集合中添加一个Integer类型的值?

*/

public class Demo {

public static void main(String[] args) throws Exception{

ArrayList strList = new ArrayList<>();

strList.add("aaa");

strList.add("bbb");

// strList.add(100);

//获取ArrayList的Class对象,反向的调用add()方法,添加数据

Class listClass = strList.getClass(); //得到 strList 对象的字节码 对象

//获取add()方法

Method m = listClass.getMethod("add", Object.class);

//调用add()方法

m.invoke(strList, 100);

//遍历集合

for(Object obj : strList){

System.out.println(obj);

System.out.println(obj.getClass());

}

/*

*Output:

* aaa

* class java.lang.String

* bbb

* class java.lang.String

* 100

* class java.lang.Integer

*/

}

}

其他方法请参考Java jdk,本文参考自Java jdk1.8

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值