JavaSE--反射

1、类的对象

基于某个类new出来的对象,也称为实例对象。

2、类对象

(1)类加载的产物

(2)封装了一个类的所有信息(类名、父类、接口、属性、方法、构造方法)

(3)一类.class文件就代表着一个类对象

3、获取类对象

(1)通过类的对象,获取类对象 

Student s = new Student();    Class c = s.getClass();

(2)通过类名获取类对象

Class c = 类名.class;

(3)通过静态方法获取类对象

Class.forName(“包名.类名”);

package com.reflects;

public class TestClassObject {
	public static void main(String[] args) {
		
//		Class c = new Class();
//		
//		c.packageName= "com.qf.day34.t3.reflects";
//		c.className = "Student";
//		c.superClass = "java.lang.Object";
//		c.fileds = new Filed[] {"String name","int age","String sex"};
//		c.methods = new methods[] {"public void study(){}","public void exam(){}","public void work(){}"};
//		c.constructors = new constructors[] {"(){}","(String name){}"};
		
		
		Student s = new Student();//类的对象。 基于模板生成的
		
		Class c = s.getClass();//类对象    是类的对象的模板
		
		System.out.println(c.toString());
	}
}
//Student.class
//Teacher.class
//Dog.class

class Student{
	String name;
	int age;
	String sex;
	public Student() {}
	public Student(String name) {
	}
	public Student(int age) {}
	
	public void study() {}
	public void exam() {}
	public void work() {}
}
package com.reflects;

public class TestGetClassObject {
	public static void main(String[] args)throws ClassNotFoundException {
		//1.通过类的对象,获取Class对象
		Person p = new Person();//类的对象
		Class c = p.getClass();//类对象(Class对象,保存了Person.class这个文件中类的所有信息)
		System.out.println(c.getName());
		
		//2.通过类名获取Class对象
		Class c2 = Person.class;
		System.out.println(c2.getName());
		
		//3.通过Class的静态方法获取Class对象
		Class c3 = Class.forName("com.qf.day34.t3.reflects.Person");
		System.out.println(c3.getName());
		
	}
	//该方法返回一个类对象(Class对象)
	public static Class getClassObject(String className) {
		Class c = null;
		try {
			c = Class.forName(className);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return c;
	}
}
class Person{	
}

4、常用方法:

JavaSE--反射_第1张图片

package com.qf.day34.t4.methods;

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

public class TestClassMethods {
	public static void main(String[] args) throws Exception{
		//1.获取类对象
		Class c = Class.forName("com.qf.day34.t4.methods.Student");
		
		System.out.println(c.getName());
		//获得指定类对象的包
		Package pack = c.getPackage();
		System.out.println(pack.getName());
		
		//获得父类的Class对象
		Class superClass = c.getSuperclass();
		System.out.println(superClass.getName());
		
		//获得接口的Class对象
		Class[] interfaces = c.getInterfaces();
		for(Class inter : interfaces) {
			System.out.println(inter.getName());
		}
		System.out.println("------------------------------------");
		//获取属性(自身+父类的公开属性)
		Field[] fields = c.getFields();
		for(Field f:fields) {
			System.out.println(f.getName());
		}
		System.out.println("-------------------");
		//获得Class对象的自身所有属性
		Field[] fields2 = c.getDeclaredFields();
		for(Field f : fields2) {
			System.out.println(f.getName());
		}
		System.out.println("------------------method--------");
		//获取方法(自身+父类的所有公开方法)
		Method[] methods =  c.getMethods();
		for(Method m :methods) {
			System.out.println(m.getName());
		}
		System.out.println("------------------method--------");
		Method[] methods2 = c.getDeclaredMethods();
		for(Method m : methods2) {
			System.out.println(m.getName()+":"+m.getReturnType());
		}
		
		System.out.println("---------constructor--------");
		Constructor[] cs = c.getConstructors();
		for(Constructor ct : cs) {
			System.out.print(ct.getName()+":");
			Class[] param = ct.getParameterTypes();//获得构造方法的形参
			for(Class p : param) {
				System.out.println(p.getName());
			}
		}
		System.out.println("------------------------");
		Object o = c.newInstance();
		Student stu = (Student)o;
		System.out.println(stu);
	}
}
class Person{
	public String sex;
	public double money;
	public void eat() {}
	public void sleep() {}
}
class Student extends Person implements Serializable,Runnable,Comparable{
	public String name;
	public int age;
	double score;
	
	public Student() {}
	public Student(String name){}
	public Student(String name,int age){}
	
	private int aaa() {
		return 0;
	}
	public void exam() {}
	public void play() {}
	@Override
	public int compareTo(Object o) {
		// TODO Auto-generated method stub
		return 0;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
	}
}

5、工厂设计模式

(1)开发中有一个非常重要的原则:“开闭原则”。对拓展开放、对修改关闭

(2)工厂模式主要负责对象创建的问题。

(3)可通过反射进行工厂模式的设计,完成动态的对象创建。

package com.reflects;

import java.lang.reflect.Method;

public class TestInvokeMethod {
	public static void main(String[] args) throws Exception {
		//反射  类的对象
		Object o = createObject("com.qf.day35.t1.reflects.Student");
		//类对象
		Class c =o.getClass();
		//name->方法名 ,parameterTypes ->参数列表类型
		Method m = c.getMethod("study",null);
		//通过invoke方法,执行某个实例方法,参数:Object->所需对象,args->调用的方法所需的实参
		m.invoke(o, null);
		//--------------------------
		Method m2 = c.getMethod("study",int.class);
		Object result = m2.invoke(o,111);//接收方法返回值,如果是基本类型,则转换为包装
		System.out.println(result);
		
//		System.out.println(c.getMethod("study", int.class).invoke(o, 111));
		//------------------------------------
		Method m3 = c.getMethod("exam", int.class,double.class,String.class);
		m3.invoke(o, 2,90,"张三");
		
		//--------------------------------
//		Method m4 = c.getMethod("calc",null); error 无法获得私有方法
		Method m4 = c.getDeclaredMethod("calc",null);//获得自身方法,包含私有
		
		//注意:反射是一种Java底层技术,可以取消语言检查。  突破封装
		m4.setAccessible(true);
		
		m4.invoke(o,null);
		
	}
	//工厂-->创建对象的
	public static Object createObject(String className) {
		try {
			Class c = Class.forName(className);
			return c.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}

class Student{
	String name;
	Integer age;
	String sex;
	Double score;
	public Student() {
	}
	public Student(String name, Integer age, String sex, Double score) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
		this.score = score;
	}
	public void study() {
		System.out.println("正在学习....");
	}
	public int study(int a ) {
		System.out.println("学习"+a+"个小时");
		return 0;
	}
	public void exam(int a ,double b,String s) {
		System.out.println(s+"正在考"+a+"个小时的测验,考了"+b+"分");
	}
	private void calc() {
		System.out.println("计算。。。。");
	}
}

6、单例模式

只允许创建一个该类的对象。

方式1:饿汉式(类加载时创建,天生线程安全);

方式2:懒汉式(使用时创建,线程不安全,需要加锁);

方式3:懒汉式(使用时创建,线程安全。无锁);

package com.singletons;

public class Test {
	public static void main(String[] args) {
		Student stu = Student.getStudent();
		Student stu1 = stu;
		Student stu2 = stu;
		System.out.println(stu);
		System.out.println(stu1);
		System.out.println(stu2);
	}
}
//只是创建了一次对象。一个对象--->只能在一个引用中
class Student{
	static int count = 0;
	//构造方法私有化
	private Student() {}
	
	public static Student getStudent() {
		count++;
		if(count>1) {
			return null;
		}else {
			return new Student();
		}
	}
}
package com.singletons;

public class TestSingleton {
	public static void main(String[] args) {
		Singleton s1 = Singleton.getInstance();
		Singleton s2 = Singleton.getInstance();
		Singleton s3 = Singleton.getInstance();
		System.out.println(s1	);
		System.out.println(s2	);
		System.out.println(s3	);	
	}
}
//懒汉式:使用时创建、天生线程安全
class Singleton{
	private Singleton() {}
	
	private static class Holder{
		static final Singleton instance= new Singleton(); 
	}
	
	
	public static Singleton getInstance() {
		return Holder.instance;
	}
}

//懒汉式:使用时创建、天生线程不安全(加同步锁);  效率低
//class Singleton{
//	private static Singleton instance = null;
//	
//	private Singleton() {}
//	
//	public synchronized static Singleton getInstance() {
//		if(instance == null) {
//			instance = new Singleton();
//		}
//		return instance;
//	}
//}



//饿汉式:天生线程安全(无锁)、类加载时创建(不用的时候,也被迫创建了,占用资源)
//class Singleton{
//	private static final Singleton instance = new Singleton();
//	
//	private Singleton() {}
//	
//	public static Singleton getInstance() {
//		return instance;
//	}
//}

 

你可能感兴趣的:(java)