java的动态性的介绍_反射机制_获取class对象的方法_获得类信息的方法_day_37;

1.java 的动态性包括:

反射机制,动态编译,动态执行JavaScript,动态字节码的操作;

2.动态语言:

Java可以被称之为  准动态语言;

3. reflection :


4.Class 这个类:

5.获得 class 对象的方法:

package Test;
/**
 * 
 * 用来测试获取class对象的类
 * 
 * @author Wang
 *
 */

public class Students {
	private int id;
	private String name;
	private String sex;
	
	public int getId() {
		return id;
	}
	
	public void setId(int id) {
		this.id = id;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public String getSex() {
		return sex;
	}
	
	public void setSex(String sex) {
		this.sex = sex;
	}
	
	public Students(int id, String name, String sex) {
		super();
		this.id = id;
		this.name = name;
		this.sex = sex;
	}
	
	public Students (){
		
	}
	
	
}
package Test;
/**
 * 
 * 我们来测试反射中class对象的获取方法
 * 和各个类的class对象是相同
 * 
 * @author Wang
 *
 */

public class getClass {
	public static void main (String[] args){
		/*
		 * 获得类的class对象  的三种方法
		 */
		
		
		//路径应该是报名  加上  类名
		String path = "Test.Students";
		//这个获取class对象的方法是我们最常用的
		//因为这个很适用于我们自己写的类  因为我们自己写的类的路径我们都知道
		//获取class对象的作用是我们可以通过这个对象获取类的全部信息
		
		try {
			
			//第一种方法
			Class class1 = Class.forName(path);
			//第二种方法
			Class class2 = String.class;
			Class class3 = String.class;
			//在这里我们会发现2和3的hashCode值一样  因为一个类只会被反射出来一次;
			System.out.println(class2.hashCode());
			System.out.println(class3.hashCode());
			//第三种方法
			int arr1[] = new int[10];
			int arr2[] = new int[20];
			double arr3[] = new double[10];
			int arr4[][] = new int[10][10];
			//数组的类型和维数会影响反射出来的类对象,但是数组的元素个数赎不回影响的
			System.out.println(arr1.getClass().hashCode());
			System.out.println(arr2.getClass().hashCode());
			System.out.println(arr3.getClass().hashCode());
			System.out.println(arr4.getClass().hashCode());
			
			
					
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		
		
		
	}
}

5.反射机制的作用:

Topic 1 : 我们用反射API  获取类信息(名字、属性、方法、构造器等)  还与上面的那个students连接 ;

代码如下:

package Test;

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

/**
 * 
 * 我们用反射API  获取类信息(名字、属性、方法、构造器等)
 * 
 * @author Wang
 *
 */
public class Demo02 {
	public static void main(String[] args){
		String path = "Test.Students";
		try {
			
			Class class1 = Class.forName(path);//获得类对象
			
			/**
			 * 获得类的名字
			 */
			
			//获得类的全名  带路径的 : Test.Students
			System.out.println(class1.getName());
			//获得类的名字  只有一个名字 :  Students
			System.out.println(class1.getSimpleName());
			
			/**
			 * 获得类的属性信息
			 */
			
			//这个是获得全部的public属性 
			Field fields[] = class1.getFields();
			//打印他的全部的public属性 : public int Test.Students.hight
			for(Field temp : fields) 
				System.out.println(temp);
			
			//获得他全部的声明过的属性
			Field[] fields1 = class1.getDeclaredFields();
			//打印他的全部属性
			for(Field temp : fields1) 
				System.out.println(temp);
			
			//获取指定的属性
			Field f = class1.getDeclaredField("name");
			
			/**
			 * 获取方法信息
			 */
			//public
			Method[] methods = class1.getMethods();
			//所有的
			Method[] methods1 = class1.getDeclaredMethods();
			//指定的
			Method m01 = class1.getDeclaredMethod("getName", null);
			//如果方法有参,则必须传递参数类型对应的class对象
			Method m02 = class1.getDeclaredMethod("setName", String.class); 
			
			for(Method temp : methods1){
				System.out.println("方法:"+ temp);
			}
			
			/**
			 * 获得构造器信息
			 */
			
			//获得无参构造
			Constructor constructor = class1.getConstructor();
			System.out.println("获得无参构造器:"+ constructor);
			//获得所有的构造器
			Constructor[] constructors = class1.getDeclaredConstructors();
			//获得带参特定的构造器
			Constructor c = class1.getDeclaredConstructor(int.class,String.class,String.class);
			System.out.println("获得带参特定构造器:"+ c);
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
}

Topic 2 :

我们利用反射来动态操作类的信息;

代码如下:

package Test;

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

/**
 * 
 * 我们通过反射的API,来动态的操作:类的信息(属性,方法,构造器等)
 * 
 * @author Wang
 *
 */

public class Demo03 {
	public static void main(String[] args){
		String path = "Test.Students";
		try {
			
			/**
			 * 这里必须用泛型说明他是Students 类型的Class  不然下面没法执行
			 * Students s = class1.newInstance();
			 */
			Class <Students> class1 = (Class <Students> ) Class.forName(path);
			//通过反射API  调用构造方法来构造对象
			//其实这里调用的是无参构造函数
			Students s = class1.newInstance();
			//System.out.println(s);
			
			
			//这里调用的是有参构造函数  同样的要加泛型
			Constructor <Students> c = class1.getConstructor(int.class,String.class,String.class);
			Students s2 = c.newInstance(1606955,"wangtong","男");
			
			
			//通过反射调用方法   注意我们字符串参数要加双引号的
			Students s3 = class1.newInstance();
			/*
			 * 这两行的作用就是  u3.setId(1234);  而他的好处就是可以从别传过来
			 * (从数据库里传过来  从浏览器中传过来)实现动态的调用 
			 */
			Method m = class1.getMethod( "setId" , int.class);
			m.invoke(s3,1234);
			
			//通过反射来操作属性
			Students s4 = class1.newInstance();
			//注意私有属性  你看看是怎么写的
			Field f = class1.getDeclaredField("name");
			/*
			 * f.set(s4, "wangtong" );
			 * 这一句运行的时候会报错  外面的方法是无法修改私有属性
			 * 解决方法如下:
			 */
			f.setAccessible(true); //设置这个属性不需要做安全检查了,可以直接访问
			f.set( s4 , "wangtong");		    //通过反射直接写属性
			System.out.println(s4.getName());	//直接使用get方法来得到属性的值
			System.out.println(f.get(s4));      //通过反射直接读属性的值
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}

}



猜你喜欢

转载自blog.csdn.net/qq_38053395/article/details/80956445
今日推荐