您的位置:首页 > 编程语言 > Java开发

java基础-反射3(反射,反射创建对象,操作对象属性,调用对象方法)

2017-12-11 15:22 1026 查看

java基础-反射3(反射,反射创建对象,操作对象属性,调用对象方法)

前面通过学习,我们了解的运行时类型信息的基本原理,以及通过Class对象和反射来获取运行时类型信息。下面来了解通过反射来创建对象,以及操作对象的属性和方法

首先还是创建一个person类

@Service
public class Person1 extends PersronParent implements PersonInterfance ,Cloneable{
public  String name;
public  double weight;
protected  double height;
private Integer age;

public Person1(){}

protected Person1(String name){
}
public void publicShow() throws Exception{
System.out.println("publicShow()");
}
protected void disPlay(){
System.out.println("disPlay()");

}

private String privateShow(String paramter1,String paramter2) throws NullPointerException{
StringBuffer stringBuffer  = new StringBuffer(paramter1);
return stringBuffer.append(paramter2).toString();
}
@Deprecated
private int testParamter(String paramter1,String paramter2) throws NullPointerException{
return 1;
}

@Deprecated
public int testPublicParamter(String paramter1,String paramter2) throws NullPointerException{
return 1;
}

@Override
public void parentSay(){
super.parentSay();
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public double getWeight() {
return weight;
}

public void setWeight(double weight) {
this.weight = weight;
}

public double getHeight() {
return height;
}

public void setHeight(double height) {
this.height = height;
}

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}

@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", weight=" + weight +
", height=" + height +
", age=" + age +
'}';
}


通过反射来创建对象

通常在java中我们有以下4中方式创建对象

通过new 关键字 创建对象

通过Object clone();方法

通过反序列化

通过反射创建

这里我们来了解通过反射来创建对象和调用方法

首先我们来看通过反射来创建对象

我们通过newInstance()来创建对象,如果对于无参数的构造方法我们直接用Class的对象的newInstance()就可以创建对象

如果对于有参数的构造方法,我们需要先获取带参数的构造器(注意权限修饰符),然后通过构造器的newInstance()方法创建对象。

public class TestReflect {

public static void main(String[] agrs){

Class<Person> personClass = Person.class;
try {
/**
* 通过无参数的构造方法创建对象
*/
Person personOne =   personClass.newInstance();
/**
* 通过有参数的构造方法创建对象
*/
Constructor constructor = personClass.getDeclaredConstructor(String.class);
Person personTwo =   (Person) constructor.newInstance("带参数");

} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}

}

}


运行结果如下



这样我们就可以通过反射来创建对象。

通过反射创建对象后可以通过反射来给操作对象的属性

通过反射操作对象属性

上一篇文章说过,类的属性在反射中使用java.lang.reflect.Field表示,当然也使用这个类来操作对象的属性,在java中属性的访问涉及到权限修饰的修饰,具体如下:



所以在操作对象的属性的需要注意对目标类属性访问的权限,如下

如果当前类对目标对象有访问的权限(如目标类属性为public)

通过Class对象的getField()获取Field。

然后通过Field的set()方法对目标对象赋值。

如果当前类对目标对象没有访问的权限(如目标类属性为private)

通过Class对象的getDeclaredField()获取Field。

调用Field 的setAccessible(true)方法,设置为可访问(如果不设置为true,则在当前类中不能访问目标类的属性,在为目标对象赋值时会报错)

然后通过Field的set()方法对目标对象赋值。

调用Field 的setAccessible(false)方法复原。

具体操作如下

public class TestFileId2 {
public static void main(String agrs[]) throws NoSuchFieldException {
try {
//获取Class 对象
Class<Person> personClass  = Person.class;
//创建目标对象(注意,我们这里直接用的object,更体现了运行时类型信息)
Object person = personClass.newInstance();
//在没有通过反射赋值之前
System.out.println("person对象在没有赋值之前");
System.out.println(person.toString());
System.out.println();

System.out.println("当前类可以操作目标类的属性:比如public权限的属性");
//获取有权限操作的属性(当前类可以操作目标对象的属性:比如public)
Field name = personClass.getField("name");
//为person 对象 的 name属性赋值为 TestName
name.set(person,"TestName");
System.out.println(person.toString());
System.out.println();

System.out.println("当前类不能够操作目标类的属性:比如private权限的属性");
Field age = personClass.getDeclaredField("age");
//为person 对象 的 age 属性设置为可访问
age.setAccessible(true);
//为person 对象 的 age属性赋值为 10
age.set(person,10);
age.setAccessible(false);
System.out.println(person.toString());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}


运行结果如下



通过反射调用对象方法

反射能够操作对象的属性,当然也可以操作对象的方法,方法通过java.lang.reflect.Method表示,由于访问权限的限制,对于方法也有如下操作

如果当前类对目标对象有访问的权限(如目标类方法为public)

通过Class对象的getMethod()获取Method。

然后通过Method的invoke()方法对目标对象赋值。

如果当前类对目标对象没有访问的权限(如目标类方法为private)

通过Class对象的getDeclaredMethod()获取Method。

调用Method的setAccessible(true)方法,设置为可访问(如果不设置为true,则在当前类中不能访问目标类的方法,在调用目标类的方法时会报错)

然后通过Method的invoke()方法对目标对象赋值。

调用Method的setAccessible(false)方法复原。

具体操作如下:

public class TestMethod2 {
public static void main(String agrs[]) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
try {
//获取Class 对象
Class<Person> personClass = Person.class;
//创建目标对象
Object person = null;
person = personClass.newInstance();

System.out.println("当前类可以操作目标类的方法:比如public权限的方法");
//获取有权限操作的方法(当前类可以操作目标对象的方法:比如public)
Method publicShow = personClass.getMethod("publicShow");
//通过Method 的invoke 调用person 的 publicShow方法
publicShow.invoke(person);

System.out.println("当前类不能够操作目标类的方法:比如private权限的方法");
Method privateShow = personClass.getDeclaredMethod("privateShow", String.class, String.class);
//为person 对象 的 privateShow 方法设置为可访问
privateShow.setAccessible(true);
//通过Method 的invoke 调用person 的 privateShow方法
String result = (String) privateShow.invoke(person, "参数1", "参数2");
System.out.println(result);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}

}


运行结果如下:



以上就是通过反射操作对象的基本方式。

反射的基础知识就是以上几篇文章,反射相对于其他知识来说比较简单,但是反射应用很多,比如很多框架,以及java中的动态代理等都涉及到了,所以反射在java中还是很重要的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐