• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
james1207

博客园    首页    新随笔    联系   管理    订阅  订阅

Java基础加强学习笔记(二)

一、反射的基础Class类

1、如何得到各个字节码对应的实例对象

(1)类名.class,例如 System.class

(2)对象.getClass(),例如 new Data().getClass()

(3)Class.forName("包.类名"),例如 Class.forName("java.util.Data")  查询或加载,即有了就用,没有就加载进来

2、九个预定义的Class实例对象

8个基本类型+1个void 

二、反射

1、定义:反射就是把java类中的各种成分映射成相应的java类。

2、构造方法的反射应用,class ->constructor -> object

(1)

 

Constructor[] constructors = Class.getName("java.lang.String").getConstructors();

(2)

 

//new String(new StringBuffer("abc"));
Constructor constructor = String.class.getConstructor(StringBuffer.class);
String str = (String)constructor.newInstance(new StringBuffer("abc"));// *.newInstance("abc")运行时错误
//String.class获得String类的字节码
//String.class.getConstructor()通过字节码获得该类的相对应的构造函数
//constructor.newInstance()通过构造函数生成该类的对象
//(String) :newInstance()返回类型为Object,多态,因此必须强制转化为String
	//Person p = new Chinese();
	//Chinese c = (Chinese)p;

 

(3)Class.newInstance()。先得到默认构造方法,即无参数的构造方法,然后利用无参数构造方法来创建对象。

利用缓存机制来保存默认构造方法的实例。

3、Field类  成员变量的反射应用

(1)使用

/*
class Student{
	private String name;
	public int age;
	public Student(String name,int age){
		this.name = name;
		this.age = age;
	}
}
*/

 

 

Student zs = new Student("zhangsan",23);
Field fieldAge = zs.getClass().getField("age");
sop(fieldZ.get(zs));

Field fieldName = zs.getClass().getDeclaredField("name");//可以得到私有的变量
fieldName.setAccessible(true);	//设置为可以访问
sop(fieldName.get(zs));			//才可以访问


//fieldZ不是一个值,而是该类的所有对象都有的一个字节码属性,通过fieldZ.get(对象)来获取某个对象的该属性的具体值

 

//getDeclaredField()

//setAccessible(true

(2)实例:改变对象中所有String类型的值中的a改为b

public void changFieldValue(Object obj) throws Exception{
	Field[] fields = obj.getClass().getFields();
	for(Field field : fields){
		if(field.getType() == String.class){		//比较字节码,唯一,故此处使用 == 而不推荐用equals()
			String oldValue = (String)field.get(obj);
			String newValue = oldValue.replace("a","b");
			field.set(obj,newValue);
		}
	}
}

 

4、Method类  方法的反射应用

(1)

/**传统方法
String str = "abc";
str.charAt(2);
*/
//反射方法

Method mycharAt = Class.getName("java.lang.String").getMethod("charAt",int.class);//

sop(mycharAt.invoke(str,2));//invoke(null,2);第一个参数如果为null,则表示为静态方法

(2)用反射方式执行某个类中的main方法

/*

传统方式

//Test.main(new String[]{"as","234"});

*/

//反射方式

 

Method method = Class.forName(className).getMethod("main",String[].class);//className类的string表示
method.invoke(null,new Object[]{new String[]{"as","234"}});


//由于jdk1.5为了兼容1.4之前的版本,故此处jvm会将参数数组拆开,作为两个参数传入.因此用object数组封装起来

 

//或者(Object)new String[]{"as","234"},告诉编译器将其作为一个对象传入,而不拆包

5、数组的反射

6、HashSet如何保证元素唯一性?

是通过元素的两个方法,hashCode()和equals()来完成。

*如果元素的HashCode值相同,才会判断equals是否为true。

*注意,对于判断元素是否存在、及删除都是依赖于以上两个方法。而ArrayList只依赖于equals()

*一般,对象存入HashSet之后,就不要修改那些hashCode()方法依赖的变量,否则会改变hashCode()的计算一致性,

此时再执行remove()等方法时无法正确操作,从而产生内存泄露。

7、框架的实现(集合)  反射应用

三、内省(IntroSpector)

用于对javaBean进行操作,javaBean特殊的java类

javaBean

1、用内省方式对javaBean的属性进行set get操作

Person p = new Person("zhangsan",23);
PropertyDescriptor pd = new PropertyDescriptor("name",p.getClass());
Method methodGetName = p.getReadMethod();
Object retVal = methodGetName.invoke(p);

Method methodSetName = p.getWriteMethod();
Object retVal = methodGetName.invoke(p,"zhang");

 

2、使用BeanUtils工具包操作javaBean

需要导入BeanUtils包以及第三方jar包(log包)

好处:(1)类型自动转换,使用String

(2)支持属性的级联 Data data = new Data();

data.time作为属性来用

(3)BeanUtils可以操作map

sop(BeanUtils.setProperty(p,"age"),"23");//参数为String

sop(BeanUtils.getProperty(p,"age"));

PropertyUtils不进行类型转换

四、注解Annotation(1.5之后)

@Override  @Deprecated  @SuppressWarnings

1、也叫元数据。相当于一种标识

2、作用分类

编写文档:通过代码里标示的元数据生成文档(生成doc文档)

代码分析:通过元数据对代码进行分析(使用反射)

编译检查:通过标示的元数据让编译器实现基本的编译检查(Override)

3、使用位置

包 类 成员变量 方法 局部变量

 

4、注解相当于一种特殊的类

5、注解的应用结构图(见知识图)

@Override    RetentionPolicy.SOURCE

@Deprecated         RetentionPolicy.RUNTIME

@SuppressWarningsRetentionPolicy.SOURCE

 

@Target(ElementType.METHOD)//该注解用在方法上

@Target({ElementType.METHOD,ElementType.Type})//该注解用在方法和类型上


Class类实现Type接口  Class  Enum  @Override  Interface 都是Type(1.5之后)

注解类

@Retention(RetentionPolicy.RUNTIME)//元注解 ,三个阶段

@Interface A{

}

使用注解类的类

@A

class B{

}

对使用注解的类使用反射

@A

class C{

if(C.class.isAnnotationPresent(A.class)){

A ann = (A)C.class.getAnnotation(A.class);  

}

}

 

6、注解的属性

 

@Retention(RetentionPolicy.RUNTIME)//元注解 ,三个阶段
@Interface A{
	String color() default "red";
	Strng value();//value()属性很特殊
	int[] arr() default {1,2,2};

}
@A(color="red",value="set",arr={1,2,3})//设置,如果只有value属性需要设置时,可以把=号省略@A("setValue")
class C{
	if(C.class.isAnnotationPresent(A.class)){
		A ann = (A)C.class.getAnnotation(A.class);  
		sop(ann.color());//使用
		sop(ann.value());//使用
		sop()
	}
}


 

 

posted @ 2013-09-25 19:08  Class Xman  阅读(186)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3