标签:android style class blog code java
Person p = new Student();
import java.lang.reflect.Method;
class Person{
public void speak(){
System.out.println("I am a person");
}
}
class Student extends Person{
public void speak(){
//覆盖父类方法
System.out.println("I am a student");
}
//子类新添加方法
public void study(){
System.out.println("Student can study");
}
}
public class PSTest {
public static void main(String[] args) throws Exception{
Person p = new Student();
//直接调用报错,因为Person中没有study()方法
//p.study();
//第1种解决方法:判断并强制转换类型
if(p instanceof Student){
Student s = (Student)p;
s.study();
}
//第2种解决方法:运行得到该对象及类信息
Class<?> clazz = p.getClass();
//得到类名
System.out.println(clazz.getName());
//甚至直接调用方法
Method m = clazz.getMethod("study");
m.invoke(p);
}
}
Package 对象包含有关 Java 包的实现和规范的版本信息。(1)Class类的静态方法forName(String clazzName),字符串参数的值是某个类的全限定类名,必须添加完整包名,注:此方法还有另一种重载形式。
(2)调用某个类的class属性来获取该类对应的Class对象,如Person.class将会返回Person类对应的Class对象。如果只有类的字符串如“java.lang.String”获取该字符串对应的Class对象,只能使用第1种方式,此方法可能抛出ClassNotFoundException异常。一旦获得某个类对应的Class对象,就可以调用Class对象的方法来获得该对象和该类的真实信息。
Class类提供了大量的实例方法来获取Class对象所对应类的详细信息,大致包含如下方法,每个方法又包含多种重载版本:
a. Constructor<?>[] getConstructors():返回此Class对象对应类的所有public构造器。
b.Constructor<T> getConstructor(Class<?>... parameterTypes):返回此Class对象对应类的指定public构造器。
c. Constructor<?>[] getDeclaredConstructors():返回此Class对象对应类的所有构造器,与构造器的访问权限无关。
d.Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes):返回此对象对应类的指定构造器,与构造器的访问权限无关。
import java.lang.reflect.Constructor;
class Person{
public Person(){
System.out.println("TestTarget");
}
public Person(String name){
System.out.println(name);
}
protected Person(String stuName,String className){
System.out.println(stuName + " - " + className);
}
private Person(String name, int age){
System.out.println(name + " - " + age);
}
}
public class GetConstructorsTest {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException{
//1.获得Class对象(共3种方式)
//1)Class.forName(String clazzName);
//Class<?> clazz = Class.forName("tad.blog.reflect.Person");
//2)类的class属性
Class<Person> clazz = Person.class;
//3)对象getClass()方法
//Class<?> clazz = new Person().getClass();
//System.out.println(clazz.getName());
//2.1.获取所有public构造器
Constructor<?>[] publicCons = clazz.getConstructors();
System.out.println("所有public构造器");
for(Constructor<?> c : publicCons){
System.out.println(c.getName());
}
//2.2.获取特定public构造器
Constructor<Person> certainCons = clazz.getConstructor(String.class);
System.out.println("特定public构造器");
System.out.println("名称:" + certainCons.getName() + ";修饰符: " + certainCons.getModifiers());
//2.3.获取所有构造器
Constructor<?>[] allCons = clazz.getDeclaredConstructors();
System.out.println("所有构造器");
for(Constructor<?> c : allCons){
System.out.println(c.getName());
}
//2.4.获取特定构造器,访问修饰符无关
Constructor<Person> certainConsPro = clazz.getDeclaredConstructor(String.class,int.class);
System.out.println("特定构造器");
System.out.println("名称:" + certainConsPro.getName() + " ;修饰符: " + certainConsPro.getModifiers());
}
}
a. Method[] getMethods():返回此Class对象所表示的类的所有public方法。
b. Method getMethod(String name,Class<?>... parameterTypes):返回此Class对象对应类的指定public方法。
c.Method[] getDeclaredMethods():返回此Class对象对应类的全部方法,与方法的访问权限无关。
d. Method getDeclaredMethod(String name,Class<?>... parameterTypes):返回此对象对应类的指定方法,与方法的访问权限无关。
import java.lang.reflect.Method;
class Fruit{
public void show(){
}
public void show(String info){
}
void getWater(){
}
protected void grow(){
}
private void deep(){
}
private void deep(int length){
}
}
public class GetMethodsTest {
public static void main(String[] args) throws NoSuchMethodException {
//1.获得Class对象
Class<Fruit> clazz = Fruit.class;
//2.1.获得所有public Method
System.out.println("所有public方法");
Method[] publicMethods = clazz.getMethods();
for(Method m : publicMethods){
System.out.println(m.getName());
}
//2.2.获得特定public Method
System.out.println("特定public方法");
Method certainMethod = clazz.getMethod("show",String.class);
System.out.println(certainMethod.getName());
//2.3.获得所有Method,修饰符无关
System.out.println("所有方法");
Method[] allMethods = clazz.getDeclaredMethods();
for(Method m : allMethods){
System.out.println(m.getName());
}
//2.4.获得特定Method,修饰符无关
System.out.println("特定方法");
Method certainMethodDeep = clazz.getDeclaredMethod("deep", int.class);
System.out.println(certainMethodDeep.getName());
}
}
import java.lang.reflect.Field;
class Animal{
public String name;
public int age;
private String secrets;
}
public class GetFieldsTest {
public static void main(String[] args) throws NoSuchFieldException {
//1.获得Class对象
Class<Animal> clazz = Animal.class;
//2.1.获得所有public字段
Field[] fields = clazz.getFields();
System.out.println("所有public字段");
for(Field f : fields){
System.out.println(f.getName());
}
//2.2.获得特定public字段
Field f = clazz.getField("name");
System.out.println("特定public字段");
System.out.println(f.getName());
//2.3.获得所有字段,访问修饰符无关
Field[] allFields = clazz.getDeclaredFields();
System.out.println("获得所有字段");
for(Field af : allFields){
System.out.println(af.getName());
}
//2.4.获得特定字段,访问修饰符无关
Field certainField = clazz.getDeclaredField("secrets");
System.out.println("获得特定字段");
System.out.println(certainField.getName());
}
}@Deprecated
@Addressing
@SuppressWarnings(value="unchecked")
class Building{
@Override
public String toString(){
return "Building";
}
}
public class GetAnnotationsTest {
public static void main(String[] args) {
//1.获得Class对象
Class<Building> clazz = Building.class;
//2.1.获得所有Annotation
System.out.println("获得所有Annotation");
Annotation[] as = clazz.getAnnotations();
for(Annotation a : as){
System.out.println(a);
}
//2.2.获得特定Annotation
System.out.println("获得特定Annotation");
Annotation a = clazz.getAnnotation(Addressing.class);
System.out.println(a);
//2.3.获得直接修饰的所有Annotation
System.out.println("获得所有Annotation");
Annotation[] ass = clazz.getDeclaredAnnotations();
for(Annotation ann : ass){
System.out.println(ann);
}
}
}a. Class<?>[] getInterfaces():返回该Class对象对应类所实现的全部接口。
b. Class<? super T> getSuperClass():返回该Class对象对应类的超类的Class对象。
interface Interfa{
}
interface Interfa2{
}
final class SuperClass implements Interfa,Interfa2{
public static class InnerClass{
public static void declaringClass() {
Class<InnerClass> clazz = InnerClass.class;
System.out.println("外部类");
System.out.println(clazz.getDeclaringClass());
}
}
}
public class TestAll{
public static void main(String[] args) {
Class<SuperClass> clazz = SuperClass.class;
//获得所有内部类
System.out.println("所有内部类");
Class<?>[] inners = clazz.getDeclaredClasses();
for(Class<?> inner : inners){
System.out.println(inner);
}
//获得外部类
SuperClass.InnerClass.declaringClass();
//获得继承父类
System.out.println("继承父类");
System.out.println(clazz.getSuperclass());
//获得实现接口
System.out.println("实现接口");
Class<?>[] inters = clazz.getInterfaces();
for(Class<?> i : inters){
System.out.println(i);
}
//获得修饰符
System.out.println("获得修饰符");
int modifier = clazz.getModifiers();
System.out.println(modifier);
//获得包
System.out.println("获得包");
Package p = clazz.getPackage();
System.out.println(p.getName());
//获得全类名及简单类名
System.out.println("全类名及简单类名");
System.out.println(clazz.getName());
System.out.println(clazz.getSimpleName());
//自我判断API
System.out.println("注解? " + clazz.isAnnotation());
System.out.println("数组? " + clazz.isArray());
SuperClass sc = new SuperClass();
System.out.println("实例? " + clazz.isInstance(sc));
}
}Class对象可以获得该类里的方法(由Method对象表示)、构造器(由Constructor对象表示)、字段(由Field对象表示),这3个类都位于java.lang.reflect包下,并实现java.lang.reflect.Member接口。程序可以通过Method对象执行对应方法,通过Constructor对象调用对应构造器创建实例,能通过Field对象直接访问并修改对象的属性值。
通过反射创建对象有以下两种方式:
(1)使用Class对象的newInstance()方法来创建该Class对象对应类的实例,这种方式要求该Class对象的对应类有默认构造器,而执行newInstance()方法实际上利用默认构造器来创建该类的实例。
(2)先使用Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建该Class对象对应类的实例。通过这种方式可以选择指定的构造器来创建实例。
通过第一种方式来创建对象是比较常见的情形,在很多JavaEE框架中都需要根据配置文件信息来创建Java对象,从配置文件读取的只是某个类的字符串类名,程序需要根据字符串来创建对应的实例,就必须使用反射。
(3)调用Constructor的newInstance()方法创建Java对象。
import java.lang.reflect.Constructor;
class Computer{
public Computer(String name){
show(name);
}
public void show(){
System.out.println("Computer");
}
public void show(String name){
System.out.println("My name is " + name);
}
}
public class ObjFactory {
public static void main(String[] args) throws Exception {
//Class<Computer> clazz = Computer.class;
//1.第1种方式创建对象
//Computer com = clazz.newInstance();
//System.out.println(com);
//com.show();
//2.第2种方式创建对象
//2.1.获取Class对象
Class<?> comClazz = Class.forName("tad.blog.reflect.Computer");
//2.2.获得指定构造器
Constructor<?> c = comClazz.getConstructor(String.class);
//2.3.创建Java对象
c.newInstance("Tad");
}
}import java.lang.reflect.Field;
class Dog
{
private String name;
private int age;
public String toString(){
return "Dog[name:"+name+",age:"+age+"]";
}
}
public class FieldTest
{
public static void main(String[] args) throws Exception
{
//创建Person对象
Dog p = new Dog();
//Person对应Class对象
Class<Dog> clazz = Dog.class;
//获取Person名为name的Field
Field nameField = clazz.getDeclaredField("name");
//取消访问权限
nameField.setAccessible(true);
//调用set方法为p对象的name字段值设置值
nameField.set(p,"Tad");//引用类型,没有Xxx,可能是因为引用类型的地址是一样的吧!
Field ageField = clazz.getDeclaredField("age");
ageField.setAccessible(true);
ageField.setInt(p,23);//8个基本数据类型,setXxx()
System.out.println(p);
}
}每个Method对象对应一个方法,获得Method对象后,程序就可以通过该Method来调用它对应的方法。在Method里包含一个invoke()方法,方法签名如下:
Object invoke(Object obj, Object...args):该方法中的obj是执行该方法的主调,后面的args是执行该方法时传入该方法的实参。
import java.lang.reflect.Method;
public class MethodTest {
public static void main(String[] args) throws Exception {
//1.获得Class对象
Class<MethodTest> clazz = MethodTest.class;
//2.获得Method对象
Method m = clazz.getMethod("show", String.class);
//3.调用invoke()方法
m.invoke(new MethodTest(), "Tad is a great person in the world.");
}
public void show(String info){
System.out.println(info);
}
}在java.lang.reflect包下还提供了一个Array类,Array对象可以代表所有的数组。程序可以使用Array来动态创建数组,操作数组元素等。
(1)static Object newInstance(Class<?> componentType, int length):创建一个具有指定的元素类型、指定维度的新数组。
(2)static xxx getXxx(Object array, int index):返回array数组中第index个元素。其中xxx是各种基本数据类型,如果数组元素是引用类型,则该方法变为get(Object array, int index)。
(3)static void setXxx(Object array, int index, xxx val):将array数组中第index个元素的值设为val,其中xxx是各种基本数据类型,如果数组元素是引用类型,则该方法变成set(Object array, int index, Object val)。
import java.lang.reflect.Array;
public class ArrayTest {
public static void main(String[] args) {
Object arr = Array.newInstance(String.class, 3);
Array.set(arr, 0, "Tad");
Array.set(arr, 1, "great");
Array.set(arr, 2, "person");
System.out.println(Array.get(arr, 0));
System.out.println(Array.get(arr, 1));
System.out.println(Array.get(arr, 2));
System.out.println("长度:" + Array.getLength(arr));
}
}
实际上,即使采用第一个方法获取了一个动态代理类之后,当程序需要通过该代理类来创建对象时一样需要传入InvocationHandler对象,也就是说,系统生成的每个代理对象都有一个与之关联的InvocationHandler对象。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface Skills{
public void bark();
public void run();
}
/**
* 委托类,业务执行者
*/
class Dog implements Skills{
public void bark() {
System.out.println("Dog can bark.");
}
public void run(){
System.out.println("Dog can run");
}
}
/**
* 调用处理类,完成代理与委托绑定
*/
class InvocationHandlerImpl implements InvocationHandler {
private Object target;
public InvocationHandlerImpl(Object target){
this.target = target;
}
/**
* 方法调用,调用代理到调用委托的转换
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(target, args);
}
}
public class DynamicProxy {
public static void main(String[] args) {
InvocationHandler h = new InvocationHandlerImpl(new Dog());
Skills o = (Skills)Proxy.newProxyInstance(Dog.class.getClassLoader(), Dog.class.getInterfaces(), h);
o.bark();
o.run();
}
}
待补充...
(2)getActualTypeArguments():返回泛型参数的类型。
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;
public class ReflectGenericTest {
public int num;
public Map<String,Integer> kv;
public static void main(String[] args) throws NoSuchFieldException {
Class<ReflectGenericTest> c = ReflectGenericTest.class;
Field fNum = c.getField("num");
System.out.println(fNum.getType());
//只能输出Map
Field f = c.getField("kv");
System.out.println(f.getType());
//获得实际类型参数
Type type = f.getGenericType();
ParameterizedType p = (ParameterizedType) type;
System.out.println("原始类型:" + p.getRawType());
Type[] types = p.getActualTypeArguments();
for(Type t : types){
System.out.println(t);
}
}
}
黑马程序员_高新技术_1_Java反射,布布扣,bubuko.com
标签:android style class blog code java
原文地址:http://blog.csdn.net/jacklearntech/article/details/29232065