黑马程序员_Java基础提高笔记1
来源:互联网 发布:linux dhcp option 67 编辑:程序博客网 时间:2024/05/20 20:57
----------------------<ahref="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<ahref="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------
黑马程序员_Java基础提高笔记1
反射的基石->Class
Class-à代表一类什么样的事物?(属性)
但是属性值是由这个类的实例来实现
Class: java程序中的各个 java类属于同一事物,描述这类事物的java类名就是class
Person p1 = new Person();
Person p2 = new Person();
Class cls1 = Date.class字节码1;
Class cls2 = Person.class字节码2;
得到类的字节码的方式:
1.System.class
2.对象.getClass()
3.class.forName(“类名”):反射时常用到,在写源程序时候不知道类的名字
P1.getClass();
Class.forName(“java.lang.String”):
有九种预定义的 Class
对象,表示八个基本类型和 void。这些类对象由 Java 虚拟机创建,与其表示的基本类型同名,即 boolean
、byte
、char
、short
、int
、long
、float
和double
。
数组类型的class实例对象: class.isArray()
只要在源程序中出现的类型,都有各自class实例对象
Stringstr1 = "abc";
Class cls1 = str1.getClass();
Class cls2 = String.class;
Class cls3 = Class.forName("java.lang.String");
System.out.println(cls1 == cls3);
System.out.println(cls2==cls3);
System.out.println(cls1.isPrimitive());
System.out.println(int .class.isPrimitive());
System.out.println(int.class == Integer.class);
System.out.println(int.class == Integer.TYPE);
System.out.println(int[].class.isPrimitive());
System.out.println(int[].class.isArray());
//new String(new StringBuffer("abc"));用反射表示如下
Constructor constructor1 =String.class.getConstructor(StringBuffer.class);
String str2 =(String)constructor1.newInstance(new StringBuffer("abc"));
System.out.println(str2.charAt(2));
反射:就是把java类中的各种成分映射到相应的java类
Constructor类:构造方法
1得到某个类所有的构造方法://方法是由字节码提供,所有的构造方法时装在数组里的
例子:Constructor [] constructors =Class.forName(“java.lang.String”).getConstructor();
2 得到某一个构造方法
例子:Constructor constructor =
Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);//获得方法时要用到类型
3.创建实例对象:
通常方式:String str = new String(newStringBuffer(“abc”));
反射方式:String str =(String)constructor.newInstance(new StringBuffer(“abc”));
//调用获得的方法时要用到上面相同类型的实例对象
4Class.NewIstance()方法:
例子:String obj= (String)Class.forName(“java.lang.String”).newInstance();
ReflectPointpt1 =new ReflectPoint(3,5);
FieldfieldY = pt1.getClass().getField("y");
//fieldY的值是多少?5?错 fieldY不是代表某个对象身上的变量值,而是类上,要用他去取某个对象对应的值
System.out.println(fieldY.get(pt1));
Field fieldX=pt1.getClass().getDeclaredField("x");//因为“x”被private了即私有了,所以要用getDeclaredField()
fieldX.setAccessible(true);//要让他可见但是也要让他可获取,用setAccessible(true):暴力反射
System.out.println(fieldX.get(pt1));
Field类:代表某个类中的一个成员变量
changeStringValue(pt1);
System.out.println(pt1);
}
private static void changeStringValue(Object obj)throws Exception{
Field[] fields =obj.getClass().getFields();//获取某个类字节码中的成员变量
for(Field field : fields){
//if(field.getType().equals(String.class)):对字节码比较用“=”比,虽然equals也行
if(field.getType()==String.class){
String oldValue=(String)field.get(obj);//获取对象的字符串
String newValue=oldValue.replace('b','a');//替换
field.set(obj, newValue);//之前替换并没把对象身上字符改变,现在设置才改
}
}
Method类代表某个类中的一个成员方法
MethodmehtodCharAt =String.class.getMethod("charAt",int.class);
System.out.println(mehtodCharAt.invoke(str1,1));//invoke是方法对象上的方法
//如果传递给Method对象的invoke()方法的第一个参数是null,那么该Method对象对应静态方法
System.out.println(mehtodCharAt.invoke(str1,new Object[]{2}));
//这是1.4的方法,因为1.4以前没有自动封装功能
例题:写一个程序能根据用户提供的雷鸣,去执行该类中的main方法
//TestArguments.main(newString[]{"111","222","333"});
//但是正常情况下是不知道类名
String startingClassName =args[0];//如果不设置,无法获得类名,则显示数组角标越界
Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);//参数是string类型的数组
mainMethod.invoke(null,new Object[]{new String[]{"111","222","333"}});//main方法时静态的所以不用传递类型
//jdk受到new string[]会把它打开,不把他当成一个数组,会认为是三个参数,所以外面要再加一个new Object[]{}打包(因为他只拆包一次)
//数组在1.4之前被认为是多个参数
//还可以直接写成mainMethod.invoke(null,(Object)new String[]{"111","222","333"});
class TestArguments{
public static void main(String[] args){
for(String arg : args){
System.out.println(arg);
}
}
}
如何给类中main()方法字符串数组参数String[] args,以至于可以在main()方法中直接调用该字符串。
在Java程序区域右击--> Run As -->Run Configuration(运行相关配置) --> 在Argument栏中,填入需要传递的实参,该实参将传递给类mai()方法
数组的反射:
int [] a1 =newint [3];
int[] a2 =newint [4];
int [][] a3 =newint[2][3];
String [] a4 = new String[3];
System.out.println(a1.getClass() == a2.getClass());
//System.out.println(a1.getClass() ==a4.getClass());在jdk1.5以下版本是可以比较的结果为false
//System.out.println(a1.getClass() ==a3.getClass());但是在1.5以后是没法比较的 false
/*对于数组类型的变量
编译器在编译时,其实已经知道类型了。也就是说,编译器认为这2个类型是不一样的。根本没有比较的需要。对于总是不成立的比较,其实是没有意义的。
这个编译错误是 JDK 1.6的新功能
*/
System.out.println(a1.getClass().getName());
System.out.println(a1.getClass().getSuperclass().getName());
System.out.println(a4.getClass().getSuperclass().getName());
Object ab1 =a1;
Object ab2 =a4;
//Object[] ab3 =a1;//基本类型不是Object
Object[] ab4 =a3;
Object[] ab5 =a4;
System.out.println(a1);
System.out.println(a4);
System.out.println(Arrays.asList(a1));//int是基本类型
System.out.println(Arrays.asList(a4));
public class ReflectTest2 {
public static void main(String[] args) {
Collection collections = newHashSet();
ReflectPoint pt1 =new ReflectPoint(3,3);
ReflectPoint pt2 =new ReflectPoint(5,5);
ReflectPoint pt3 =new ReflectPoint(3,3);
collections.add(pt1);
collections.add(pt2);
collections.add(pt3);
collections.add(pt1);
pt1.y = 7;
collections.remove(pt1);//该对象的哈希值已经改变,所以移除的并不是原来对象。常时间
//出现这种情况会出现“内存泄漏”
System.out.println(collections.size());
}
}
比较符: == : 是根据对象的值来比较的。
equals(): 是根据所比较的对象的哈希码来比较的。哈希码通常是根据内存地址换算来的。
如果==比较结果是true,那么equals()方法得到的必然也是true,但是,反之则不一定成立。
但是,当两个对象的值相等,但是哈希值不等,即默认的equals()方法下,他们并不相等,那么,如何编程覆盖equals()方法,使之相等?其实,
是指如果两个对象相等,那么只存储其中一个。
Eclipse中提供了快速覆盖equals()的方法,右击 --> Source --> GenerateHashCode() and equals() --> 选择比较的变量。
----------------------<ahref="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<ahref="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------
- 黑马程序员_Java基础提高笔记1
- 黑马程序员_java基础_java异常笔记
- 黑马程序员_java基础(1)
- 黑马程序员_Java基础1
- 黑马程序员_Java基础1
- 黑马程序员_java基础1
- 黑马程序员_java基础(1)
- 黑马程序员_java基础(1)
- 黑马程序员_java基础(1)
- 黑马程序员_java基础(1)
- 黑马程序员_java提高(回炉1)
- 黑马程序员_Java基础笔记(面向对象1)
- 黑马程序员_Java基础笔记01
- 黑马程序员_Java基础笔记 --动态代理
- 黑马程序员_Java基础学习笔记
- 黑马程序员_Java基础学习笔记2
- 黑马程序员_JAVA基础加强笔记
- 黑马程序员_java基础笔记(04)...多线程
- spring获取JavaBean的几种方式
- 简单的单例实现
- Animation动画类
- Android ListView 去除边缘阴影、选中色、拖动背景色等
- Beagle选型参数对照表
- 黑马程序员_Java基础提高笔记1
- java中的单例模式和工厂模式举例:
- jquery 遍历
- UIView的layoutSubviews和drawRect方法何时调用
- JSON基础笔记
- 黑马程序员_java征途开始之前
- Android编程之横屏竖屏切换及状态保存
- 我的第一个博客
- windows64位安装SetupTools