反射详解

私以为:每一个对象有隐式引用指向它的Class对象,Class对象可能会指向方法区的Class类型

TestReflect1.java

package 反射及类型信息;
//类名的取得
public class TestReflect1 {
	public static void main(String[] args) {
		TestReflect1 tf1 = new TestReflect1();
		System.out.println(tf1.getClass());          //class 反射及类型信息.TestReflect1
		System.out.println(tf1.getClass().getName());   //反射及类型信息.TestReflect1
		System.out.println(tf1.getClass().getSimpleName());   //TestReflect1
	}
}

TestReflect2.java

package 反射及类型信息;
//类加载的方式
public class TestReflect2 {
	public static void main(String[] args) throws Exception {
		Class class1 = null;
		Class<?> class2 = null;
		Class<?> class3 = null;
		
		//一般采用这种形式
		class1 = Class.forName("反射及类型信息.TestReflect2");  //即getClass().getName();
		class2 = new TestReflect2().getClass();
		class3 = TestReflect2.class;
		System.out.println("类名称     "+class1.getName()); 
                                                //类名称   反射及类型信息.TestReflect2
		System.out.println("类名称     "+class2.getName());
                                                //类名称   反射及类型信息.TestReflect2
		System.out.println("类名称     "+class3.getName());
                                                //类名称   反射及类型信息.TestReflect2
        
        System.out.println(class1==class2);   //true
        System.out.println(class3==class2);   //true
        //以上说明了Class对象只有一个
	}
}

TestReflect3.java

package 反射及类型信息;
//类的继承类和接口
import java.io.Serializable;
import java.util.Comparator;

public class TestReflect3 implements Serializable,Cloneable,Comparator{
	private static final long serialVersionUID = -2862585049955236662L; 
	public static void main(String[] args) throws ClassNotFoundException {
		Class<?> clazz = Class.forName("反射及类型信息.TestReflect3");
		//取得父类
		Class<?> parentClass = clazz.getSuperclass();
		System.out.println("clazz的父类为: "+parentClass.getName());
		Class<?> intes[] = clazz.getInterfaces();
		System.out.println("clazz实现的接口有: ");
		for(int i=0;i<intes.length;i++){
			System.out.println((i+1)+":"+intes[i].getName());
		}
	}
	@Override
	public int compare(Object o1, Object o2) {
		return 0;
	}
}

clazz的父类为: java.lang.Object
clazz实现的接口有: 
1:java.io.Serializable
2:java.lang.Cloneable
3:java.util.Comparator

TestReflect4.java

在Java中,一般情况下会使用new关键字来调用类的有参或者无参构造函数来建立一个对象,也可以通过Class.newInstance()方法来调用类的无参构造函数来建立一个对象。

而如果一个类的构造函数为private 类型,不是public类型的话,那么new关键字和Class.newInstance()方法都将没有用武之地。这也是为什么我们通过把构造函数设置为private类型来实现单例模式的原因,Java反射就可以通过一种方式绕过私有构造函数来创建对象的。那就是通过Constructor对象来实现

package 反射及类型信息;
//查看某个类的全部构造函数,通过反射机制实例化一个类的对象
import java.lang.reflect.Constructor;

class User{
	private int age;
	private String name;
	private User() {
		super();
	}
	public User(int a,int b) {
		super();
	}
	public User(int age, String name) {
		super();
		this.age = age;
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
}
public class TestReflect4 {
	/*
	 * Class<T>在实例化的时候,T要替换成具体类
	 *	Class<?>它是个通配泛型,?可以代表任何类型
	 */
	public static void main(String[] args) throws Exception {
		Class<?> class1 = null;
		class1 = Class.forName("反射及类型信息.User");
		User user0,user1;
		user0 = user1 = null;
		//第一种方法,实例化默认构造方法,调用set赋值
		/* private不能通过此方法构造对象
		User user = (User)class1.newInstance();
		user.setAge(20);
		user.setName("Rollen");
		System.out.println(user);*/
		
		//第二种方法  取得全部的构造函数  使用构造函数赋值,只能获得public 类型的构造器
		Constructor<?> cons[] = class1.getConstructors();
		System.out.println(cons[0].getParameterCount());
		System.out.println(cons[1].getParameterCount());

		//查看每个构造方法需要的函数
		for(int i=0;i<cons.length;i++){
			Class<?>[] clazzs = cons[i].getParameterTypes();
			for(int j=0;j<clazzs.length;j++){
				System.out.print(i + " " + clazzs[j].getName()+ "  ");
			}
			System.out.println();
		}
		
//		cons[0].setAccessible(true);
//		user0 = (User) cons[0].newInstance();
//		System.out.println(user0);
		
		user0 = (User) cons[0].newInstance(10,"Bell");
		System.out.println(user0);
		
		/*下面也可以
		Constructor<?> cs = class1.getDeclaredConstructor();
		cs.setAccessible(true);
		User user = (User)cs.newInstance();
		 */
		//下面 0 1 2是一个个试出来的
		Constructor<?> cs[] = class1.getDeclaredConstructors();
		System.out.println(cs.length);
		cs[2].setAccessible(true);
		User temp = (User)cs[2].newInstance();
		System.out.println(temp);
	}
}

2
2
0 int  0 java.lang.String  
1 int  1 int  
反射及类型信息.User@15db9742
3
反射及类型信息.User@6d06d69c

TestReflect5.java

扫描二维码关注公众号,回复: 2611275 查看本文章

不仅能获得类型还能获得变量名

package 反射及类型信息;

//通过反射获取属性

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

//getFields()与getDeclaredFields()的区别
/*
getFields()只能访问类中声明为公有的字段包括从父类和接口继承而来的字段,其他字段无法访问 
getDeclaredFields()能访问类中所有的字段,与public、private、protected无关,不能访问从其他类继承来的属性 
getMethods()只能访问类中声明为公有的方法包括从父类和接口继承而来的方法,其他方法无法访问 
getDeclaredMethods()能访问类中所有的方法,与public、private、protected无关,不能访问从其他类继承来的方法 
getConstructors()只能访问类中声明为公有的构造器其他无法访问 
getConstructors()能访问类中所有的构造器,与public、private、protected无关
构造器不能继承 
*/
public class TestReflect5 implements Serializable{
	private static final long serialVersionUID = -2862585049955236662L;
	public static void main(String[] args) throws Exception {
		Class<?> clazz = Class.forName("反射及类型信息.jutiClient");
		//取得本类的所有属性
		
		Field[] fields = clazz.getDeclaredFields();
		for(int i=0;i<fields.length;i++){
			//权限修饰符
			int mo = fields[i].getModifiers();
			String priv = Modifier.toString(mo);
			//属性类型
			Class<?> type = fields[i].getType();
			System.out.println(priv+" "+type.getName()+" "+fields[i].getName()+";");
		}
		System.out.println("=============================================");
		//取得实现的接口或者父类的属性
		Field[] fieldss = clazz.getFields();
		for(int j=0;j<fieldss.length;j++){
			//权限修饰符
			int mo = fieldss[j].getModifiers();
			String priv = Modifier.toString(mo);
			//属性类别
			Class<?> type = fieldss[j].getType();
			System.out.println(priv+" "+type.getSimpleName()+" "+fieldss[j].getName()+";");
		}
	}
}
class Client{
	public int age;
	private String name;
	public Client() {
		super();
	}
	public Client(int age, String name) {
		super();
		this.age = age;
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}
class jutiClient extends Client{
	private int ziji;
	public String jizi;
}

private int ziji;
public java.lang.String jizi;
=============================================
public String jizi;
public int age;

TestReflect6.java

package 反射及类型信息;

//通过反射获取类的方法
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class TestReflect6 implements Serializable{
	private static final long serialVersionUID = -2862585049955236662L;
	public static void main(String[] args) throws Exception {
		Class<?> clazz = null;
		clazz = Class.forName("反射及类型信息.TestReflect6");
		Method methods[] = clazz.getMethods();
		for(int i=0;i<methods.length;i++){
			Class<?> returnType = methods[i].getReturnType();
			Class<?> para[] = methods[i].getParameterTypes();
			int temp = methods[i].getModifiers();
			System.out.print(Modifier.toString(temp)+" "+returnType.getSimpleName()+" "+methods[i].getName()+" ");
			System.out.print("(");
			for(int j=0;j<para.length;j++){
				System.out.print(para[j].getSimpleName()+" "+"arg"+j);
				if(j<para.length-1){
					System.out.print(",");
				}
			}
			System.out.print(")");
			Class<?> exce[] = methods[i].getExceptionTypes();
			if(exce.length>0){
				System.out.print(" throws ");
				for(int k=0;k<exce.length;k++){
					System.out.print(exce[k].getSimpleName()+" ");
					if(k<exce.length-1){
						System.out.print(",");
					}
				}
			}
			System.out.println();
		}
	}
	public void ownTest(int a,String b) throws Exception{
		
	}
}

public static void main (String[] arg0) throws Exception 
public void ownTest (int arg0,String arg1) throws Exception 
public final void wait () throws InterruptedException 
public final void wait (long arg0,int arg1) throws InterruptedException 
public final native void wait (long arg0) throws InterruptedException 
public boolean equals (Object arg0)
public String toString ()
public native int hashCode ()
public final native Class getClass ()
public final native void notify ()
public final native void notifyAll ()

TestReflect7.java

package 反射及类型信息;

import java.lang.reflect.Method;

//通过反射机制调用某个类的方法
public class TestReflect7 {
	public static void main(String[] args) throws Exception {
		Class<?> clazz = Class.forName("反射及类型信息.TestReflect7");
		Method method = clazz.getMethod("reflect1");
		method.invoke(clazz.newInstance());
		
		method = clazz.getMethod("reflect2", int.class,String.class);
		method.invoke(clazz.newInstance(), 20,"张三");
	}
	public void reflect1(){
		System.out.println("Java反射机制-调用某个类的方法1");
	}
	public void reflect2(int age,String name){
		System.out.println("age->"+age+"  "+"name->"+name);
	}
}

Java反射机制-调用某个类的方法1
age->20  name->张三

TestReflect8.java   可参考https://blog.csdn.net/codefunjava/article/details/39718843

package 反射及类型信息;

import java.lang.reflect.Field;

//通过反射操作某个类的属性
public class TestReflect8 {
	private String property = null;
	public static void main(String[] args) throws Exception {
		Class<?> clazz = Class.forName("反射及类型信息.TestReflect8");
		Class<?> clazz1 = Class.forName("反射及类型信息.AA");
		
		Object obj = clazz.newInstance();
		Object obj1 = clazz1.newInstance();
		
		Field field = clazz.getDeclaredField("property");
		Field field1 = clazz1.getDeclaredField("property");
		//field.setAccessible(false);
		field.set(obj, "自己的私有属性可以不setAccessible 设置false、true都能访问 Java反射机制");
		field1.setAccessible(true);
		field1.set(obj1, "Java反射机制");
		
		System.out.println(field.get(obj));
		System.out.println(field1.get(obj1));
	}
}
class AA{
	private String property = null;
}

自己的私有属性可以不setAccessible Java反射机制
Java反射机制

猜你喜欢

转载自blog.csdn.net/qq_27378875/article/details/81388185