您的位置:首页 > 职场人生

黑马程序员——JAVA基础------反射

2015-07-31 10:54 399 查看
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——

一、Class类

Java 程序中的各个 Java 类属于同一类事物,描述这类事物的 Java 类名就是Class。Class 类是一切反射的根源。

得到Class类的对象有三种方式:

类名.class ,例如,System.class

对象.getClass(),例如,new Date().getClass()

Class.forName(“类名”),例如,Class.forName(“java.util.Date”)

九个预定义的Class实例对象:

boolean , byte , char , short , int , long , float , double ,void

数组类型的Class实例对象

Class.isArray();

代码演示:

package com.joe.reflect;

public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
String str1 = "abc";
Class cls1 = str1.getClass();
Class cls2 = String.class;
Class cls3 = Class.forName("java.lang.String");
System.out.println(cls1 == cls2);   //返回true
System.out.println(cls1 == cls3);   //返回true

System.out.println(cls1.isPrimitive());             //返回false
System.out.println(int.class.isPrimitive());        //判断是否为基本类型        返回true
System.out.println(int.class == Integer.class);     //返回false
System.out.println(int.class == Integer.TYPE);      //返回true
System.out.println(int[].class.isPrimitive());      //返回false
System.out.println(int[].class.isArray());          //判断是否为数组类          返回true
}

}


使用Class类进行对象的实例化操作

1、 调用无参构造进行实例化

public T newInstance() throws InstantiationException,IllegalAccessException


2、调用有参构造进行实例化

public Constructor<?>[] getConstructor() throws SecurityException


二、Constructor类

Constructor类代表某个类中的一个构造方法

得到某个类所有的构造方法:

例子:

Constructor[] constructors =Class.forName("java.lang.String").getConstructors;


得到某一个构造方法:

例子:

Constructor consturctor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);


创建实例对象:

通常方式:

String str = new String(new StringBuffer("abc"));


反射方式:

String str = (String)constructor.newInstance(new StringBuffer("abc"));


ps:调用获得的方法时要用到上面相同类型的实例对象

Class.newInstance()方法:

例子:

String obj = (String)Class.forName("java.lang.String").newInstance();


该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。

三、Field类

Field类代表某个类中的一个成员变量

得到的Field对象是对应到类上面的成员变量,而不对应到对象上的成员变量。

例如:

定义一个类:

package com.joe.reflect;

import java.lang.reflect.Field;

class ReflectDemo01 {
private int x;
public int y;

public ReflectDemo01(int x, int y) {
super();
this.x = x;
this.y = y;

}

}

public class ReflectPoint {

public static void main(String[] args) throws Exception {
ReflectDemo01 pt1 = new ReflectDemo01(3, 5);
Field fieldY = pt1.getClass().getField("y");
System.out.println(fieldY);          //返回类的地址
System.out.println(fieldY.get(pt1)); // 返回 5

}

}


四、Method类

Method类代表某个类中的一个成员方法

得到类中的某一个方法:

Mehtod charAt = Class.forName("java.lang.String").getMethod("charAt",int.class);


调用方法:

通常方式:

System.out.println(str.charAt(1));


反射方式:

System.out.println(charAt.invoke(str,1));


ps:如果传递给Method对象的invoke()方法的第一个参数为null,说明Method对象对应的是一个静态方法!

调用类中的方法:

调用类中的方法,传入实例化对象,以及具体的参数内容

public Object invoke(Object obj,Object... args)


直接调用属性:

取得属性

public Object get(Object obj)


设置属性,等同于使用“=”完成操作

public void set(Object obj,Object value)


让属性对外部可见

public void setAccessible(boolean flag)


代码演示:

package com.joe.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class RefDemo {

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

Person p1 = new Person("joe", 18, '男');
Person p2 = new Person("kay", 19, '女');

// 一个Class对象代表着一份字节码,相同类型的对象得到的字节码对象是同一个
// 创建Class对象的方式一:对象.getClass()
Class personClass1 = p1.getClass();
Class personClass2 = p2.getClass();
System.out.println(personClass1 == personClass2); // 返回true
// 创建Class对象的方式二:类.class
Class personClass3 = Person.class;
System.out.println(personClass1 == personClass3); // 返回true
// int.class;
// void.class;
// 创建Class对象的方式三:Class.forName("类的全名")
// Class.forName会报ClassNotFoundException
Class personClass4 = Class.forName("com.joe.reflect.Person");
System.out.println(personClass1 == personClass4); // 返回true

// ---------通过类信息实例化对象---------
// 调用无参构造方法
try {
// 调用此方法时要注意,如果类中没有无参构造方法,将会报异常InstantiationException(实例化异常)
Person p3 = (Person) personClass4.newInstance();
System.out.println(p3);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
// 调用有参构造方法
Constructor[] cs = personClass4.getConstructors();// 获取当前类的所有构造方法
for (Constructor c : cs) {
System.out.println(c.getName());
Class[] paramsTypes = c.getParameterTypes();
for (Class class1 : paramsTypes) {
System.out.println(class1);
}
System.out.println("--------------------");
}
Person p4 = null;
try {
// 获取指定参数类型的构造方法
Constructor c1 = personClass4.getConstructor(String.class,
int.class, char.class);
p4 = (Person) c1.newInstance("lusi", 17, '女');
System.out.println(p4);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println("-----------获得类信息-----------------");
System.out.println("包信息:" + personClass4.getPackage().getName());
System.out.println("类名:" + personClass4.getName());
// 返回一个包含某些 Method 对象的数组,
// 这些对象反映此 Class 对象所表示的类或接口
// (包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。

System.out.println("----获取方法信息---");
Method[] ms = personClass4.getMethods();
for (int i = 0; i < ms.length; i++) {
Method m = ms[i];
System.out.println("方法名:" + m.getName());
}
// 返回 Method 对象的一个数组,这些对象反映此 Class
// 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
System.out.println("-----------------------");
Method[] ms2 = personClass4.getDeclaredMethods();
for (int i = 0; i < ms2.length; i++) {
Method m = ms2[i];
System.out.println("方法名:" + Modifier.toString(m.getModifiers())//获得修饰符
+ "  " + m.getName());
}

System.out.println("-----获取属性信息----------");
// 返回一个包含某些 Field 对象的数组,
// 这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。
Field[] fs = personClass4.getFields();
for (int i = 0; i < fs.length; i++) {
System.out.println(fs[i].getName());
}
System.out.println("---------------------");
Field[] fs2 = personClass4.getDeclaredFields();
for (int i = 0; i < fs2.length; i++) {
System.out.println(fs2[i].getName());
}
System.out.println("-------------调用方法和属性-----------------");
System.out.println("---调用方法----");
try {
Method setNameMethod = personClass4.getMethod("setName",
String.class);
// 调用方法
setNameMethod.invoke(p4, "kay");// p4.setName("kay");
System.out.println(p4);
Method sayMethod = personClass4.getDeclaredMethod("say");
sayMethod.setAccessible(true);// 忽略检查访问修饰符
sayMethod.invoke(p4);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println("------调用属性-------");
try {
Field ageField = personClass4.getDeclaredField("age");
ageField.setAccessible(true);// 忽略检查访问修饰符
System.out.println(ageField.get(p4));// 获取p4的age属性值
ageField.set(p4, 18);// 给p4对象的age属性赋值
System.out.println(p4);
} catch (Exception e) {
e.printStackTrace();
}
}

}

class Person {
private String name;
private int age;
private char sex;

// 私有方法
private void say() {
System.out.println("my name is " + name);
}

public Person(String name, int age, char sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
System.out.println("Person带参构造方法");
}

public Person() {
super();
System.out.println("Person无参构造方法");
}

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 char getSex() {
return sex;
}

public void setSex(char sex) {
this.sex = sex;
}

@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]";
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java-反射