黑马程序员_java反射
2015-07-21 13:27
656 查看
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);
}
}
通过反射获取构造方法:
获取构造方法有两种情况,一是无参构造方法,二是有参构造方法。
示例:
获取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(null, null);
}
//获取私有方法
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;
代码:
每一个类的实例对象在内存中都有相对应的字节码。
一个类被类加载器加载到内存中,占用储存空间,而在该储存空间中的就是该类的字节码,不同类的字节码是不同的,所以在内存中也是不相同的。
在内存中占用的空间可以用对象来表示,这些对象的类型就是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(null, null);
}
//获取私有方法
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; } }
相关文章推荐
- 黑马程序员_java集合2
- 黑马程序员——java基础——多线程的学习总结
- 黑马程序员_java集合1
- Android面试题Activity部分
- 黑马程序员_javaAPI
- java基础面试题
- 如何提高程序员的逼格
- 黑马程序员--iOS--C基础(一)
- 剑指offer-面试题5.从尾到头打印链表
- 黑马程序员---面向对象中的内部类
- 黑马程序员—JAVA基础—String类 javaAPI学习
- 面试时可以向面试官提那些问题
- 推荐!国外程序员整理的 PHP 资源大全
- 剑指offer-面试题4.替换空格
- 告别迷茫与忧伤的程序员
- 面试-阻塞队列及线程池
- 面试-锁相关
- 面试-并发概述
- 面试-JVM
- 黑马程序员—— 6,多态