黑马程序员---------Java面向对象——反射
来源:互联网 发布:零之镇魂曲 知乎 编辑:程序博客网 时间:2024/06/03 06:31
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ---
反射
理解反射的概念
反射就是把Java类中的各种成分映射相成Java类。
例如:众多的人用一个Person类来表示,那么众多的Java类就用一个Class类来表示。
反射也称为对类的解剖。把类的各个组成部分映射成一个个相应的Java类。
例如:一个类有:成员变量,方法,构造方法,包等等信息。
利用反射技术可以对一个类进行解剖。
其实只要拿到Java类的字节码对应的Class对象,就等于拿到了Java类中的各个成分。
反射的基石就是Class。
Class类
Class类用于表示.class文件,是所有加载进内存的字节码对象的父类。所以可以通过Class得到运行时的类。
图例分析:
代码体现:
先定义一个Person类:
package com.itheimaday26;
public class Person {
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
private String name;
private int age;
public Person(){
super();
System.out.println("person run");
}
Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public void show(String name,int age){
System.out.println("show run....name="+name+",age="+age);
}
public static void staticShow(){
System.out.println("staticShow run");
}
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;
}
}
package com.itheimaday26;
public class Reflect_getClass {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
/*
* 要想获取字节码文件中的成员,必须要先获取字节码文件对象。
*
* 获取字节码文件对象的方式:
*
* 1,通过Object类中的get.Class方法。
*
* 虽然通用,但是前提必须有指定的类。并对该类进行对象的创建,才可以调用getClass方法。
*
* 2,使用的任意数据类的一个静态成员Class,所有的数据类型都具备的一个属性。
*
* 好处:不用new对象。但是,还需要使用
*
* 3,使用Class/类中的forName方法。通过给定类名来获取对应的字节码文件对象。
*
* (static Class<?> forName(String className)
*
* 返回与带有给定字符串名的类或接口相关联的 Class对象。 )
*
* 这种方式很爽,只要知道类的名字就可以了。获取对应的字节码文件直接由forName方法来完成。
*
* 这就是反射技术使用的获取字节码文件对象的方式。
*
*/
// getClass_1();
// getClass_2();
getClass_3();
}
private static void getClass_3() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//先有类名(类名是字符串)
/*
* 1,通过给定的类名称,加载对应的字节码文件,并封装成字节码文件对象Class
*
*/
String className ="com.itheimaday26.Person";
Class clazz = Class.forName(className);
// System.out.println(clazz);
//通过newInstance()就可以创建字节码对象所表示的类的实列
/*
* 2,通过new创建给定类的实例。
*
* 3,调用该类的构造函数。
*
* 通常被反射的类都会有提供空参数的构造函数。
*
* 没有对应的构造函数,会报 InstantiationException异常
*
* 如果有提供,但是权限不够,会报无效的权限访问异常 IllegalAccessException(权限不够异常 常见的)
*/
Object obj = clazz.newInstance();
/*
* 1,加载Person类,并将Person类封装成字节码文件对象。
*
* 2,通过new创建Person对象。
*
* 3,调用构造函数对对象初始化。
*
*/
//总结:方法一虽然代码长点。但是扩展性要强很多 ,不用new对象都可以。
// Person p = new Person();
System.out.println(obj);
}
private static void getClass_2() {
Class clazz = Person.class;
System.out.println(clazz.getName());
}
private static void getClass_1() {
Person p1 = new Person();
Person p2 = new Person();
Class clazz1 = p1.getClass();
Class clazz2 = p2.getClass();
System.out.println(clazz1 == clazz2);// true
// System.out.println(clazz.getName());//获取类的名字
}
}
package com.itheimaday26;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;public class Reflect_GetConstructor {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {/* * 如果要通过指定的构造函数初始化对象怎么办呢? * * 思路: * * 1,获取字节码文件对象。 * * 2,在获取给定构造函数。 * * 3,通过构造函数初始化对象。 * */getConstructor();}private static void getConstructor() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {String className ="com.itheimaday26.Person";Class clazz = Class.forName(className);//获取指定的构造器。获取Person类中两个参数String ,int的构造函数。//(Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) // 返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。 )Constructor cons = clazz.getDeclaredConstructor(String.class,int.class);//有了构造器对象后,通过构造器对象来初始化给类对象。//( T newInstance() // 创建此 Class 对象所表示的类的一个新实例。 )//Person p = new Person("lisi",30);Object obj = cons.newInstance("lisi",30);//传递参数System.out.println(obj);//System.out.println(p);}}package com.itheimaday26;import java.lang.reflect.Field;public class Reflect_GetFiled {public static void main(String[] args) throws ClassNotFoundException,NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {/* * 获取字段。 */getFiledDemo();}private static void getFiledDemo() throws ClassNotFoundException,NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {String className = "com.itheimaday26.Person";Class clazz = Class.forName(className);String fileName = "age";// 获取字段。age对象// Field filed = clazz.getField(fileName);//获取公共的字段Field filed = clazz.getDeclaredField(fileName);System.out.println(filed);// 备注:getXXX:获取的都是公共的成员。// getDeclaredXXX :获取本类中已有的成员 无所谓权限的限制。// 正常思路的设置参数年龄:// Person p = new Person();// p.age =10;//对其进行值的设置,必须先有对象。Object obj = clazz.newInstance();//通过查找父类AccessibleObject的方法。setAccessible(true);//AccessibleObject 类是 Field、Method 和 Constructor 对象的基类。//它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控制检查的能力。//对于公共成员、默认(打包)访问成员、受保护成员和私有成员,在分别使用 Field、Method 或 Constructor//对象来设置或获取字段、调用方法,或者创建和初始化类的新实例的时候,会执行访问检查。filed.setAccessible(true);//(取消权限,暴力访问) 一般不访问私有,需要的话就此方法暴力访问 比较麻烦。filed.set(obj, 30);//IllegalAccessException age字段是私有的。System.out.println(obj);}}package com.itheimaday26;import java.lang.reflect.Method;public class Reflect_GetMethod {public static void main(String[] args) throws Exception {/* * 获取方法: *///getMethodDemo();getMethodStaticDemo();}private static void getMethodStaticDemo() throws Exception {String className = "com.itheimaday26.Person";Class clazz = Class.forName(className);String methodName = "staticShow";Method method = clazz.getMethod(methodName,null);method.invoke(null, null);}private static void getMethodDemo() throws Exception {String className = "com.itheimaday26.Person";Class clazz = Class.forName(className);// 拿到方法名String methodName = "show";Method method = clazz.getMethod(methodName, String.class, int.class);// 常规思维执行(一个方法被调用必须知道对象 还有就是传递世界参数)/* * Person p = new Person(); * * p.show("zhangsan", 32); */Object obj = clazz.newInstance();// (newInstance() 创建此 Class// 对象所表示的类的一个新实例。)method.invoke(obj, "zhangsan", 32);}}
- 黑马程序员--Java面向对象——反射
- 黑马程序员---------Java面向对象——反射
- 黑马程序员——java面向对象
- 黑马程序员——java:面向对象
- 黑马程序员——Java面向对象
- 黑马程序员——java-面向对象
- 黑马程序员——JAVA面向对象
- 黑马程序员——JAVA面向对象
- 黑马程序员——java面向对象
- 黑马程序员——Java面向对象
- 黑马程序员—java面向对象一
- 黑马程序员—java面向对象二
- 黑马程序员 java基础<—>--->面向对象
- 黑马程序员—JAVA面向对象
- 黑马程序员—Java面向对象
- 黑马程序员—Java之面向对象
- 黑马程序员—面向对象
- 黑马程序员—面向对象
- Linux Raw Socket使用总结
- lua_settable
- 士兵杀敌(三)rmq
- poj 2104 K-th Number(线段树)
- C语言extern和static--2014.10.10
- 黑马程序员---------Java面向对象——反射
- Java中的类与对象
- Java基础加强_Eclipse、枚举、反射、注解、泛型、类加载器、动态代理
- spring3国际化 动态语言切换
- Segment公司--整合数据进行分析
- 优化小技巧
- Autolayout及VFL
- Java深度历险 读书总结(一)
- HTTP通信原理