黑马程序员_java反射

来源:互联网 发布:java字符流写入文件 编辑:程序博客网 时间:2024/05/19 14:55

Java程序中的各个类属于同一事物,描述这类事物的java类名就是Class,想要学习反射就必须先理解Class。

每一个类的实例对象在内存中都有相对应的字节码。


一个类被类加载器加载到内存中,占用储存空间,而在该储存空间中的就是该类的字节码,不同类的字节码是不同的,所以在内存中也是不相同的。


在内存中占用的空间可以用对象来表示,这些对象的类型就是Class。

概念:


JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。


Java反射就是把java类中的各种成分映射成相对应的java类


Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。


想要对一个类进行反射,必须获取该类的字节码文件,因为反射是在运行时才调用类的方法和对象,所以避过编译期的一些异常,如:可用反射在Integer泛型的集合中,添加String类型的元素,而不报异常。

获取字节码文件的三种方式


1.Class clazz = 对象.getClass();

通过对象获取字节码文件对象


2.Class clazz = 类名.class;

每一个数据类型都具备静态的class属性


3.Class clazz = Class.forName(“类名”);

Class类的forName();静态方法,只需要传入一个字符串类名,这种方法最为常用。


示例:

package itheima;

 

public class Person {

private String name;

private int age;

public Person()

{

System.out.println("hello reflect");

}

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;

}

public Person(String name,int age)

{

this.name=name;

this.age=age;

System.out.println(name+":::::"+age);

}

}

package itheima;

 

public class GetClass {

 

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

//第一种方式

Person p = new Person();

Class c1 = p.getClass();

System.out.println(c1);

System.out.println("------------------------------");

//第二种方式

Class c2 = Person.class;

System.out.println(c1);

System.out.println("------------------------------");

//第三种方式

Class c3 = Class.forName("itheima.Person");

System.out.println(c1);

}

 

}


通过反射获取构造方法:

获取构造方法有两种情况,一是无参构造方法,二是有参构造方法。

 

示例:

package itheima;public class Person {private String name;private int age;public Person(){System.out.println("hello reflect");}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;}public Person(String name,int age){this.name=name;this.age=age;System.out.println(name+":::::"+age);}}package itheima;import java.lang.reflect.Constructor;public class GetConstructor {public static void main(String[] args) throws Exception{String name = "itheima.Person";//得到该类的名字//把类加载进内存,产生Class对象Class clazz = Class.forName(name);createConstructor1(clazz);createConstructor2(clazz);}//方法一,通过Object类中的newInstance方法,获取Person类的无参构造函数public static void createConstructor1(Class clazz)throws Exception{Object obj = clazz.newInstance();//调用类的无参构造方法}//方法二,通过的到构造方法对象,在进行初始化public static void createConstructor2(Class clazz)throws Exception{//获取指定的构造方法对象Constructor constructor = clazz.getConstructor(String.class,int.class);//通过构造器对象的newInstance方法对对象进行初始化Object obj = constructor.newInstance("剑圣",20);}}


获取Class字段:

示例:

package itheima;

 

public class Person {

private String name;

private int age;

public Person()

{

System.out.println("hello reflect");

}

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;

}

public Person(String name,int age)

{

this.name=name;

this.age=age;

System.out.println(name+":::::"+age);

}

}

 

package itheima;

 

import java.lang.reflect.Field;

 

public class GetField {

 

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

//得到该类的名字

String name = "itheima.Person";

//把类加载进内存,产生Class对象

Class clazz = Class.forName(name);

//得到字段对象,getDeclaredField()既可以获取公共方法,又可以获取私有方法

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

//暴力访问,取消私有的访问权限

field.setAccessible(true);

//得到构造方法

Object obj1 = clazz.newInstance();

//为指定的字段赋值

field.set(obj1, "赵信");

//获取指定的字段

Object obj2 = field.get(obj1);

//打印指定的字段

System.out.println(obj2);

 

}

 

}


获取Class的方法

示例:

package itheima;

 

public class Person {

private String name;

private int age;

public Person()

{

System.out.println("hello reflect");

}

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;

}

public Person(String name,int age)

{

this.name=name;

this.age=age;

System.out.println(name+":::::"+age);

}

public static void staticMethod1(String str)

{

System.out.println("有参数的静态方法:"+str);

}

public static void staticMethod2()

{

System.out.println("无参数的静态方法:");

}

private void privateMethod()

{

System.out.println("私有方法");

}

public void paramentMethod(String str)

{

System.out.println("有参数方法");

}

public void paramentMethod()

{

System.out.println("无参数方法");

}

}

package itheima;

 

import java.lang.reflect.Method;

 

public class GetMethod {

 

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

//得到该类的名字

String name = "itheima.Person";

//把类加载进内存,产生Class对象

Class clazz = Class.forName(name);

//得到该类的所有方法,存入集合中

Method[] methods = clazz.getDeclaredMethods();

//遍历出该类的所有方法

for(Method method : methods)

{

System.out.println(method);

}

m1(clazz);

m2(clazz);

m3(clazz);

m4(clazz);

m5(clazz);

}

//获取有参数的静态方法

public static void m1(Class clazz)throws Exception

{

//得到该类的指定方法对象

Method method = clazz.getDeclaredMethod("staticMethod1", String.class);

//调用该类的指定方法

method.invoke(null"瑞雯");

}

//获取无参数的静态方法

public static void m2(Class clazz)throws Exception

{

//得到该类的指定方法对象

Method method =clazz.getDeclaredMethod("staticMethod2"null);

//调用该类的指定方法

method.invoke(nullnull);

}

//获取私有方法

public static void m3(Class clazz)throws Exception

{

//得到该类的指定方法对象

Method method = clazz.getDeclaredMethod("privateMethod"null);

//暴力访问,取消私有的访问权限

method.setAccessible(true);

//得到该类的对象

Object obj = clazz.newInstance();

//调用该类的指定方法

method.invoke(obj, null);

}

//获取无参数一般方法

public static void m4(Class clazz)throws Exception

{

//得到该类的指定方法对象

Method method = clazz.getDeclaredMethod("paramentMethod"null);

//得到该类的对象

Object obj = clazz.newInstance();

//调用该类的指定方法

method.invoke(obj, null);

}

//获取有参数一般方法

public static void m5(Class clazz)throws Exception

{

//得到该类的指定方法对象

Method method = clazz.getDeclaredMethod("paramentMethod", String.class);

//得到该类的对象

Object obj = clazz.newInstance();

//调用该类的指定方法

method.invoke(obj, "蛮三刀");

}

 

}



题目:

把points类中的所有字符串对象中的a换成b;

代码:

import java.lang.reflect.*;class FiledsTest {public static void main(String[] args) throws Exception{Points p1 = new Points(1,3);filedsDemo(p1);System.out.println(p1);}public static void filedsDemo(Object obj)throws Exception{Field[] fields = obj.getClass().getDeclaredFields();//得到所有字段,包括私有字段for(Field field : fields)//遍历该类的所有字段{if(fields.getType() == String.class)//判断是否为字符串类型{field.setAccessible(true);//暴力访问String oldValue = (String)field.get(obj);//得到指定字段的值String newValue = oldValue.replace('a','b');//字符串的替换field.set(obj,newValue);//设置指定的字段的值}}}}class Points{private int x;public int y;private String str = "aaa";public String str1 = "aca";private String str2 = "abc";public Points(int x,int y){this.x=x;this.y=y;}public String toString(){ return str+":::::"+str1+":::::"+str2;}}



0 0
原创粉丝点击