Java-反射的基本知识点解析

一、什么是类对象
1.类的对象:基于某个类new出来的对象,也称为实例对象。
2.类对象:类加载的产物,封装了一个类的所有信息(类名、父类、接口、属性、方法、构造方法)
在这里插入图片描述
3.类Class
由此Class对象建模的类的类型。例如,String.class的类型是Class。如果被建模的类未知,则使用Class<?>
public final class Class extends Object implements Serizlizable,GenericDeclaration,Type,AnnotatedElement
Class类的实例表示正在运行的Java应用程序中的类和接口。枚举是一种类,注销是一种接口。每个数组属性被映射Class对象的一个类,所有具有相同元素类型和维数的数组都共享该Class对象。基本的Java类型(boolean、byte、char、short、int、long、float和double)和和关键字void也表示为Class对象。
Class没有公共构造方法。Class对象是在加载类是由Java虚拟机以及通过调用加载器中的defineClass方法自动构造的。

二、获取类对象的方法
一个Class对象就代表了一个.class文件
1.通过类的对象,获取类对象
Student s = new Student();//类的对象
Class c = s.getClass();//类对象(Class对象,保存了Student.class这个文件的所有信息)
2.通过类名获取对象
Class c = 类名.class;
3.通过静态方法获取类对象
Class c = Class.forName(“包名.类名”);
//获得类对象(Class对象)
public static void getClassObject(String className){
try{ Class c = Class.forName(className);
} catch(ClassNotFoundException e){
e.printStackTrace();}}
4.常用方法
public String getName();//以String的形式返回此Class对象所表示的实体(类、接口、数组类、基本数据类型或void)名称。

public Package getPackage()//获取此类的包。此类的类加载器用于查找该包。如果该类是通过引导类加载器加载的,则搜索从CLASSPATH加载的包的集合,以查找该类的包。如果所有包对象都不是用该类的类加载器加载的,则返回null
只有该类的附属清单中定义了信息,并且类加载器使用该清单中的属性创建了包实例,包才具有版本和规范属性。
返回:该类的包,如果存档或基本代码中没有可用的包信息,则返回null

public Class<? super ?> getSuperclass()返回表示此Class所表示的实体(类、接口、基本类型或void)的超类的Class

public Class<?>[] getInterfaces()//确定此对象所表示的类或接口实现的接口

public Field[] getFields() //返回一个包含某些Field对象的数组,这些对象反映此Class对象所表示的类或接口的所有可访问公共字段。
public Field[] getDeclaredFields()//返回一个Field对象的一个数组,这些对象反映此Class对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
//自身所有属性

public Method[] getMethods()返回一个包含某些Method对象的数组,这些对象反映此Class对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共membr方法

public Constructor<?>[] getConstructors()//返回一个包含某些Constructor对象的数组,这些对象反映此Class对象所表示的类的所有公共构造方法。
Constructor提供关于类的单个构造方法的信息以及对它的访问权限
Constructor允许在将参与带有底层构造方法的形参newInstace()匹配时进行扩展转换,但是如果发生收缩转换,则抛出IllegalArrgumentException
public Constructor getConstructors(Class<?>… parameterTypes)
返回一个Constructor对象,它反映此class对象所表示的类的指定公共构造方法。
parameterTypes可指定类型 如 String Double等按重载的规则

public T newInstance()//创建此Class对象所表示的一个新实例

///

package reflects;
main(){
	Class c = Class.forName(“reflescts.Teacher”);
	//类相关信息(数据)
	System.out.println(c.getName());//获取类名
	System.out.println(c.getPackage().getName());
	//获取分父类Class对象
	Class superclass = c.getSuperclass();
	System.out.println(superclass.getName());
	//获得所有接口的Class对象
	Class[] interfeces = c.getInterfaces();
	for(Class inters : interfaces){
	System.out.println(interfaes.getName());}
	//获取所有属性的Field对象
Field[] fields = c.getFields();//获取自身+父类的公开属性
for(Field field : fields){
System.out.println(“getFields方法:”+filed.getName());}

------------------------------

Field[] fields2 = c.getDeclaraedFields();//获取自身所有属性
for(Field field : fields2){
System.out.println(“getDeclaraedFields方法:”+filed.getName());}
//获取自身所有的方法除私有
Method[] methods = c.getMethods();
for(Method method : methods){
System.out.println(method.getName());}
//-----------------------
Method[] methods2 = c.getDeclaredMethods();//获取私有方法
for(Method method : methods2){
System.out.println(method.getName());}
//拿到构造方法的名字
Constructor[] cs =c.getConstructors();
for(Constructor constructor : cs){
System.out.println(constructor.getName());}
}

class Person{ public Interger age; public String sex;}
class Teacher extends Person implements Serializable,Runnable,Comparable{
public String name;
public Double salary;
String address;//家庭住址
public Teacher(){}
Public Teacher(String name,Double salary){}
public void run(){}
public int compareTo(Object o){return 0;}}

main(){
	//使用手工的形式new对象
	Student s = new Student();
	s.name = “tom”; //不能保证属性在更换类后还存在
System.out.println(s.name);
//使用反射创建类的对象该方法灵活通用
Class c = Student.class;
Student s2 =(Student)c.newInstance();//调用方法
//System.out.println(s2.tuString());
s2.name= “Jack”;
System.out.println(s2.name)//-------------------
Object o = createObject(“used.Student”);
System.out.println(o);//使用父类作为方法返回值实现多态
}
//通用编程
public static Object createObject(String className){
try{Class c = Class.forName(ClassName);//用传过来的名字作为参数
	return c.newInstace();
}catch(Exception e){
e.printStackTrace();}
return null;}
class Student{
String name;
Integer age;
String sex;
Double score;
public void study(){
System.out.println(“name:+name);}
public Double exam(){
System.out.println(“考试”);
calc();
return score;}
privte void calc(){
System.out.println(“演算”);}
}

main(){
Reader fr = new FileReader(“informations\\application.txt”);
BufferedReader br = new BufferedReader(fr);
String className = br.readLine();
Object obj = factory(className);
System.out.println(obj);}
public staic Object factort(String className) throws Exception{
Class c = Class.forName(className);
return c.newInstance();}


三、常见操作
四、设计模式介绍
五、单例设计模式
1.单例(Singleton):只允许创建一个该类的对象

2.方式1:饿汉式(类加载时创建,天生线程安全)不好,不用的时候也被迫创建,占用一点点资
class Singleton{
private static final Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return instance;}} 
	3.方式2:懒汉式(使用时创建,线程不安全,加同步)
class Singleton{
private static Singleton instance = null;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;}
}
4.方式3:懒汉式(使用时创建,线程安全)
class Singleton{
private Singleton(){}
private static class Holder{//只有访问内部类才给
static Singleton s = new Singleton();}
public static Singleton instance(){
return Holder.s;}}

main(){
Singleton s = Singleton.getInstance();
System.out.println(s);
Class.forName(“singleton.Singleton”);
}
class Singleton{
private static final Singleton instance = new Singleton();//封装
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
}
六、工厂设计模式
1.开发中有一个非常重要的原则“开闭原则”,对拓展开发、对修改关闭
2.工厂模式主要负责对象创建的问题
3.可通过反射进行工厂模式的设计,完成动态的对象创建。
///
Object invoke(Object obj,Objtct…ags) 对带有指定参数的指定对象调用由此Method对象表示的底层方法。
在这里插入图片描述

main(){
	//通过工厂创建一个类(Student)的对象
	Object stu = objectFactory(“invokes.Student”);
	//Class c = Class.forName(“invokes.Student”);
//通过学生对象获得了所属的类对象(Class –> invokes.Student)
Class c = stu.getClass();//通过学生对象拿到类对象
//通过类对象获得了其中的一个方法(study方法、无参)
Method m = c.getMethod(“study”,null);//通过类对象拿到方法
//通过invoke,让study实例方法执行起来,所需的对象,作为第一个参数,所需的方法调用实参,作为第二个参数。
m.invoke(stu,null);//指定对象stu.study()  null指无参
//-------------------
Method m2 =c.getMethod(“study”,int.class);
m2.invoke(stu,111);
//----------
Method m3 =c.getMethod(“study”,int.class,double.class);
m3.invoke(stu,111,2.3);
//--------------
Method m4 =c.getDeclaredMethod(“calc”,null);
//注释:反射是一种Java的底层技术,可以突破封装
m4.setAccessible(true);//无视封装//权限过大容易造成危险
m4.invoke(stu.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;
}
public void study(){
System.out.println(study() Excuted”);}
public int study(int a){
System.out.println(study(int a) Excuted”);
return 0;}
public Double exam(int a, double b){
System.out.println(exam(int a, double b) Excuted”);
calc();
return score;}
privte void calc(){
System.out.println(calc() Excuted”);}
}

Test{
main(){
invokeAny(new Student(),“exam”,new Class[]{int.class,double.class},111,2.3);
Properties prop = new Properties();
invokeAny(prop, “setProperty”,new Class[]{String.class,Strig.class}, “CN”, “中国”);
System.out.println(prop.getProperty(“CN”));
}
//通用编程(调用任何一个方法)
public static void invokeAny(Object obj , String methodName,Class[] types,Object ... args)throws Exception{
//获得类对象
Class c = obj.getClass();
//获得方法对象Method
Method m = c.getDeclaredMethod(methodName,types);
//执行方法
m.invoke(obj,args);
}}
      

在这里插入图片描述
在这里插入图片描述//
七、总结
类对象
Class对象,封装了一个类的所有信息;程序运行中,可通过Class对象获取类的信息
获取类对象的三种方式
Class c = 对象.getClass();
Class c = 类名.class;
Class c = Class.forName(“包名.类名”);
工厂模式
主要用于创建对象,通过反射进行工厂模式的设计,完成动态的对象创建
单例模式
Singleton,只允许创建一个该类的对象

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值