Java基础38-反射机制

1.Java反射

就是Java程序在运行时,可以加载、探知、使用编译期间完全未知的类。也就是说,Java程序可以加载一个运行时才得知类名的类,获得类的完整构造方法,并实例化出对象,给对象属性设定值或者调用对象的方法。这种在运行时动态获取的类的信息以及动态调用对象的方法的功能称为Java的反射机制。

例如:

package cn.lanqiao01;

public class Test01 {
	
	public String name1=null;
	public String name2=null;
	public Test01(String name1,String name2) {
		this.name1=name1;
		this.name2=name2;
	}

}

and;

package cn.lanqiao01;

public class Car extends Test01 {
	
	public Car(String name1, String name2) {
		super(name1, name2);
		// TODO Auto-generated constructor stub
	}

	public void show() {
		
		System.out.println(name1+"========"+name2);
	}

}

and;

package cn.lanqiao01;

public class Test02 {
	String name="驾驶员";
	public Test02(String name) {
		this.name=name;
	}
	public static void main(String[] args) {
		Car car = new Car("战神","长城");
		Test02 test02 = new Test02("柳海龙");
		test02.callShow(car);
	}
	//编译 时知道需要传入的参数是Test01类型
	public static void callShow(Car v){
		v.show();//调用Test01类相关的方法
	}
}

作为程序员,编写简单的Java程序时,使用反射机制的机会不多。反射机制一般在框架中使用较多,因为框架要适用更多的情况,对灵活性要求较高,而反射机制正好能解决这种灵活性要求。

package cn.lanqiao01;

import java.lang.reflect.Method;
import java.util.Scanner;

public class Test03 {
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入一个Java类全名:");
		String cName = sc.next();
		showMethods(cName);
	}
	public static void showMethods(String name) {
		try {
			Class c = Class.forName(name);
			Method m[] = c.getDeclaredMethods();
			System.out.println("该Java类的方法有:");
			for(int i=0;i<m.length;i++) {
				System.out.println(m[i].toString());
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
}

结果:

请输入一个Java类全名:
java.lang.Object
该Java类的方法有:
protected void java.lang.Object.finalize() throws java.lang.Throwable
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
private static native void java.lang.Object.registerNatives()

and;

请输入一个Java类全名:
cn.lanqiao01.Car
该Java类的方法有:
public void cn.lanqiao01.Car.show()

2.Class类

在JDK中,java.lang.reflect包提供了类和接口,以获得关于类和对象的反射信息。反射机制允许通过编程,访问关于加载类的属性、方法和构造方法的信息,并允许使用反射对属性、方法和构造方法进行操作。java.lang包中的Class类和java.lang.reflect包中的Method类,Field类、Constructor类、Array类将是本章重点介绍的内容。

3.Class类概述

与多数反射机制用到的类不同,Class类在java.lang包中,不在java.lang.reflect包中。Class类继承自Object类,是Java反射机制的入口,封装了一个类或接口的运行时信息,通过调用Class类的方法可以获取这些信息。

下面列举了获取Class类的几种方法:

  • Class.forName()

Class c = Class.forName("java.lang.Object");

  • 类名.class

Calss c = Car.class;

  • 包装类.TYPE

Class c = Integer.TYPE;

  • 对象名.getClass()

String name = "大力士";

Calss c = name.getClass();

  • Class 类.getSuperClass()

Class c = String.class.getSuperClass();

这里务必要注意,只有通过Class类.get SupeClass()方法才能获得Class类的父类的Class对象。不能通过name.getSuperClass()获取name对象父类的Class对象。

package cn.lanqiao01;


public class Test {
	public static void main(String[] args) {
		//如果将被建模的类类型未知,用Class<?>表示
		Class<?> c1=null;
		Class<?> c2=null;
		Class<?> c3=null;
		Class<?> c4=null;
		Class<?> c5=null;
		try {
			//建议采用这种形式
			c1=Class.forName("java.lang.Object");
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		c2 = new Test().getClass();
		c3=Test.class;
		String name = new String("大力士");
		c4=name.getClass();
		c5=name.getClass().getSuperclass();
		System.out.println("Class.forName(\"java.lang.Object\")类名称:"+c1.getName());
		System.out.println("new Test().getClass()类名称:"+c2.getName());
		System.out.println("Test().class 类名称:"+c3.getName());
		System.out.println("name.getClass() 类名称:"+c4.getName());
		System.out.println("name.getClass().getSuperclass() 类名称:"+c5.getName());
	}
	
}

结果:

Class.forName("java.lang.Object")类名称:java.lang.Object
new Test().getClass()类名称:cn.lanqiao01.Test
Test().class 类名称:cn.lanqiao01.Test
name.getClass() 类名称:java.lang.String
name.getClass().getSuperclass() 类名称:java.lang.Object

4.Class类常用方法

  • Field[] getFields();

返回一个包含Field对象的数组,存放该类或者接口的所有可访问公共属性(含继承的公共属性)。

  • Field[] getDeclaredFields();

返回一个包含Field对象的数组,存放该类或接口的所有属性(不含继承的属性)。

  • Field getField(String name);

返回一个指定公共属性名的Field对象。

  • Method[] getMethods();

返回一个包含Method对象数组,存放该类或接口的所有可访问公共方法(含继承公共方法)。

  • Method[] getDeclaredMethod();

返回一个包含MEthod对象数组,存放该类或接口的所有方法(不含继承的方法)。

  • Constructor[] getConstructors();

返回一个包含Constructor对象的数组,存放该类的所有公共构造方法。

  • Constructor[] getConstructor(Class[] arge);

返回有个指定参数列表的Constructor对象。

  • Class[] getInterfaces();

返回一个包含Class对象的数组,存放该类或接口实现的接口。

  • T newInstance();

使用无参构造方法创建该类的新实例。

  • String getName();

以String的形式返回该类(类、接口、数组类、基本数据类型或void)的完整名。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值