认识Class类
- 所有类的对象实际上都是Class类的实例
- Class类常用方法
- 实例化Class类对象的三种方法
package study;
import java.lang.*;
class X{
}
public class demo {
public static void main(String[] args) {
Class<?>c1=null;
Class<?>c2=null;
Class<?>c3=null;
try{
c1=Class.forName("study.X"); //最常用的形式
}catch (ClassNotFoundException e){
e.printStackTrace();
}
c2=new X().getClass();//通过Object类中的方法实例
c3=X.class;//通过类.Class实例化
System.out.println("类名称");
System.out.println(c1+"\t"+c2+"\t"+c3);
}
}
Class类的使用
- 通过无参构造实例化对象,通过newInstance
- 调用有参构造实例化对象
1.通过Class类中的getConstructors()取得本类中所有的构造方法
2.向构造方法中传递一个对象数组进去,里面包含了构造方法中所需的各个参数
3.之后通过Constructor实例化对象 - Constructor常用方法
package study;
import java.lang.*;
class Person {
private String name;
private int age;
//public Person(String name,int age){
// this.name=name;
// this.age=age;
//}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String toString() {
return "姓名" + this.name + "年龄" + this.age;
}
}
public class demo {
public static void main(String[] args) {
Class<?> c=null;
try{
c=Class.forName("study.Person");
}catch (ClassNotFoundException e){
e.printStackTrace();
}
Person per=null;
//Constructor<?> cons[]=null;
//cons=c.getConstructors();
try{
per=(Person)c.newInstance();
//per=(Person)cons[0].newInstance("小明",30);
}catch (Exception e){
e.printStackTrace();
}
per.setAge(15);
per.setName("小明");
System.out.println(per);
}
}
反射的应用
- Constructor:表示类中的构造方法
- Field:表示类中的属性
- Method:表示类中的方法
(三个类都是AccessibleObject类的子类)
1.取得所实现的全部接口(getInterfaces())
Class<?>c1=null;
try
{ c1=Class.forName("study.Person");}
catch(ClassNotFoundException e)
{e.printStackTrace();}
Class<?>c[]=c1.getInterfaces();
for(int i=0;i<c.length;i++){System.out.println("实现的接口名称"+c[i].getName);}
2.取得父类(getSuperclass(),getName())
3.取得全部构造方法(Constructors类
)
- 取得Person类中的全部构造方法
- 取得一个类的全部构造方法
1.
Constructors<?> con[]=c1.getConstructors();
for(int i<con.length) System.out.println(con[i]);
2.
for(i<con.length){
Class<?>p[]=con[i].getParameterTypes(); //列出构造中的参数类型
"构造方法:"+Modifier.toString(con[i].getModifiers());//取出权限
+con[i].getName();//输出构造方法名称
for(j<p.length){
p[j].getName()+"arg"+i;
}
}
//输出结果:构造方法: public study.Person(){} or (java.lang.String arg1,int arg2){}
4.取得全部方法(Method类)
5.取得全部属性(Field类)
- 得到实现的接口或父类中的公共属性:public Field[] getFields() throws SecurityException
- 得到本类中的全部属性:public Field[] getDeclaredFields() throws SecurityException
- 以上返回的都是Field数组,每一个Field对象表示类中的一个属性
- Field类常用方法
- 可用getModifiers().toString()取得修饰符
java反射机制的深入应用
通过反射调用类中的方法
如果要使用反射调用类中的方法可以通过Method类完成,操作步骤如下:
(1)通过Class类的getMethod(String name,Class…parameterTypes)方法取得一个Method的对象,并设置此方法操作时所需要的参数类型
(2)之后可以使用invoke()进行调用,并向方法中传递要设置的参数
Class.forName()-------1.实例化Class--->Person
getMethod("sayChina")--------2.找到sayChina()--->+sayChina():void
invoke()------->3.调用方法--->+sayChina():void
调用setter及getter方法
package study;
import java.lang.*;
import java.lang.reflect.Method;
class Person {
private String name;
private int age;
public Person(){
}
public Person(String name){
this.setName(name);
}
public Person(String name,int age){
this.name=name;
this.age=age;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "姓名" + this.name + "年龄" + this.age;
}
}
public class demo {
public static void main(String[] args) {
Class<?> c1 = null;
Object obj=null;
try{
c1=Class.forName("study.Person");
}catch (ClassNotFoundException e){
e.printStackTrace();
}
try{
obj=c1.newInstance();
}catch (InstantiationException e){
e.printStackTrace();
}catch (IllegalAccessException e){
e.printStackTrace();
}
setter(obj,"name","小明",String.class);
setter(obj,"age",15,int.class);
System.out.println("姓名:");
getter(obj,"name");
System.out.println("年龄:");
getter(obj,"age");
}
public static void setter(Object obj,String att,Object value,Class<?>type){
try{
Method met=obj.getClass()
.getMethod("set"+initStr(att),type);
met.invoke(obj,value);
}catch (Exception e){
e.printStackTrace();
}
}
public static void getter(Object obj,String att){
try{
Method met=obj.getClass().getMethod("get"+initStr(att));
}catch (Exception e){
e.printStackTrace();
}
}
public static String initStr(String old){
String str=old.substring(0,1).toUpperCase()+old.substring(1);
return str;
}
}
通过反射操作属性
通过反射操作数组
- 可以通过Class类的以下方法取得一个数组的Class对象
public Class<?>getComponentType()
- 在反射操作抱java.lang.reflect中使用Array类表示一个数组,可以通过此类取得数组长度,取得数组内容的操作
- Array类的常用方法
动态代理
可以通过一个代理类完成全部的代理功能,那么此时就必须使用使用动态代理完成.
在java中实现动态代理机制,则需要java.lang.reflect.InvocationHandler接口和java.lang.reflect.Proxy类的支持
在此接口中只定义了一个invoke()方法,此方法有三个参数,其参数的意义如下.
Object proxy:被代理的对象
Method method:要调用的方法
Object args[]:方法调用时所需要的参数
Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类.Proxy提供了如下的操作方法:
通过newProxyInstance()方法可以动态地生成实现类,在此方法中的参数意义如下.
ClassLoader loader:类加载器
Class<?>[]interfaces:得到全部的接口
InvocationHandler h:得到InvocationHandler接口的子类实例
类的生命周期
工厂设计模式
将反射机制应用在工厂模式上
package study;
import java.io.FileInputStream;
import java.lang.*;
import java.lang.reflect.Method;
interface Fruit{
public void eat();
}
class Apple implements Fruit{
public void eat(){
System.out.println("吃苹果");
}
}
class Orange implements Fruit{
public void eat() {
System.out.println("吃橘子");
}
}
class Factory{
public static Fruit getInstance(String className){
Fruit fruit=null;
try{
fruit=(Fruit)Class.forName(className).newInstance();//实例化对象
}catch (Exception e){
e.printStackTrace();
}
return fruit;
}
}
public class demo {
public static void main(String[] args) {
Fruit f=Factory.getInstance("study.Apple");
if(f!=null) f.eat();
}
}
结合属性文件的工厂模式
package study;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.lang.*;
import java.lang.reflect.Method;
import java.util.Properties;
interface Fruit{
public void eat();
}
class Apple implements Fruit{
public void eat(){
System.out.println("吃苹果");
}
}
class Orange implements Fruit{
public void eat() {
System.out.println("吃橘子");
}
}
class Factory{
public static Fruit getInstance(String className){
Fruit fruit=null;
try{
fruit=(Fruit)Class.forName(className).newInstance();//实例化对象
}catch (Exception e){
e.printStackTrace();
}
return fruit;
}
}
class init{
public static Properties getPro(){
Properties pro=new Properties();
File f=new File("d:\\fruit.properties");
try{
if(f.exists()){
pro.load(new FileInputStream(f));
}
else {
pro.setProperty("apple", "study.Apple");
pro.setProperty("orange", "study.Orange");
pro.store(new FileOutputStream(f), "FRUIT CLASS");
}
}catch (Exception e){
e.printStackTrace();
}
return pro;
}
}
public class demo {
public static void main(String[] args) {
Properties pro=init.getPro();
Fruit f=Factory.getInstance(pro.getProperty("apple"));
if(f!=null) f.eat();
}
}