黑马程序员——Java基础加强—高新技术

时间:2022-01-16 15:42:31
                                        黑马程序员——Java基础加强—高新技术
---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、
<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------   


一、Eclipse集成开发环境:
   Eclipse :2011年11月,IBM投资4000万美元贡献给开源社区。Eclipse 是支持多语言的开发平台。它的价值是为可扩展的集成开发环境提


供了一个开放源码平台,这个平台允许任何人构建与环境和其他工具无缝集成的工具(插件)。Eclipse除了一个小型的运行时核心之外,其


余的都是插件。
IDE:Integrated Development Environment,集成开发环境。


 1、在Eclipse 中设置快捷键:
窗口—属性—生成—编辑——键管理
Windows->Preferences->General -> Editors ->Key (Content Assist:内容助理)


2.在Eclipse里面如何调试查看一个变量的值?
(看到甲壳虫图标,就是调试模式)
a.debug as:在Debug透视图进行调试。
b.选中要调试的变量,右击选择Watch。  
常用:


F5:调入调试内部
F6:单步调试下一步不进入函数内部。 
F7:由函数内部返回到调用处。 
F8:直执行到下一个断点。 
(4)Ctrl+Pg~ --对于XML文件是切换代


3.设置模板 
Windows->Preferences->General -> Editors ->Templates


Syso 会 自动补全System.out.println();
或者 Alt+/ 快捷键


4.Eclipse插件安装方法:
1.拷贝安装。
2.Links安装:eclipse目录下创建links目录>>在links下创建link文件,指定插件路径。path=D:/Plugins-    Download/GEF-All-3.1;一个


link文件里面可以添加多个path。
3.Update安装。只要知道插件的更新地址就行。Help>>software update>>find and install>>选择“search for new features to install


”>>next >>“New Renote Site”,添加新的站点后,按eclipse更新向导就可以完成插件安装了。


插件查看:
帮助—关于Eclipse —软件安装
Help >>About Eclipse SDK>>Plug-in Details
            
二.JDK1.5新特性:
泛型:使用泛型来接收类中操作的引用数据类型 <>
当类中的操作的引用数据类型不确定的时候,可以使用泛型表示.
好处:1.运行时期的问题转换成编译失败,体现在编译时期,方便程序员解决问题,编译不通过,更不可能运行成功。
      2.避免强转的麻烦
      
泛型技术:其实应用在编译时期,是给编译器使用的技术,到了运行时期,泛型就不存在了
泛型的擦除:编辑器检查了泛型的类型正确后,在生成的类文件中是没有泛型的。  
泛型的补偿:因为存储的时候,类型已经确定了是同一个类型的元素,所以在运行时,只要获取到该元素的类型,在内部进行一次转换即可。


泛型定义:
1.定义在类上:泛型类定义的泛型在整个类中都有效,泛型类对象明确操作类型后,所有操作类型都固定啦。
2.定义在方法上:静态方法使用泛型只能定义在方法上
3.泛型定义在接口上
方法上:
 public static <Q> void function(Q t) { 
System.out.println("function:"+t); 

接口上:
package com.itheima.connection;


public class GenericDemo5 {


/**
* @param args
*/
public static void main(String[] args) {
InterImpl i=new InterImpl<>();
i.show(4);
i.show("haha");


}


}
interface Inter<T>{
void show(T t);
}


class InterImpl<T> implements Inter<T>{


@Override
public void show(T t) {
System.out.print("show:"+t);

}

}
泛型的限定:
上限:?extends E:可以接收E类型或者E的子类型对象。 
下限:?super E:可以接收E类型或者E的父类型对象。


可变参数:当一个方法要处理的参数不确定时,则可以设置可变参数
格式:参数类型 ....变量名


 public class TestParameter {  
     public static void main(String[] args) {
         System.out.println(add(1,2,3,4,5));
         System.out.println(add(1,3));
     }




     public static int add(int... number){ 
        int sum = 0 ;
        for (int i = 0 ; i < number.length ; i++) {
            sum += number[i] ;
        }
        return sum ;
    }
 
 }


 有多个参数累加 ,要放到最后 pbulc static int add(int x,int ....arg)
 
2.增强for循环:foreach语句简化了迭代器


格式:for(元素类型、变量名:Connection集合&数组){


}




增强for循环用在迭代器中 参数(声明变量 、迭代内容)


1.Collection 单列集合
ArraList al=new ArryList()
al.add("hao123");
al.add("5858");
for(Object o:al){ 
String s=(String)o
System.out.println(s); 
}
2.使用在Map集合中:
Map集合原则是是不能实现for迭代的,Map没有Iterator 方法。
jdk5中新定义的接口,就一个方法iterator方法,只有实现了Iterable接口的类,才可保证有Iterator方法,
增强for内部还是用迭代器实现的,要将Map转为Set。
Map map = new HashMap();
 map.put(1, "a");  
 map.put(2, "b"); 
 
 Set entrySet=map.entrySet();//获取Entry 键值对象
 Iterator it=entrySet.iterator();
 while(it.hasNext()){
    Map.Entry en=(Entry)it.next();
    Integer key=(Integer)en.getKey();   //分别获取Key 和Value值
    String  value=(String)en.getValue();
    
    System.out.println(key + "=" + value); 
 }
 
 使用 for增强:
 for(Object obj:map.entrySet()){
       Map.Entry entry = (Entry) obj;  // obj 依次表示Entry 迭代的内容        
 }     System.out.println(entry.getKey() + "=" + entry.getValue()); 
 
3.递归:函数自身调用自身,功能内部又用到了该功能,但是传递的参数不确定。
递归的使用:1.一定要定义递归的条件
            2.递归的次数不宜太多,否则会发生栈内存溢出。(栈内存中不断的加载同一个函数)
            
4.枚举:1.某个类型变量取值只能未若干个固定值,否则会报错,枚举可以再编译时就控制非法值收入。
        2.枚举成员只有一个,就可以作为为单例模式实现。


如:定义星期变量只能是周一到周日 1-7


package com.itheima.reflect.demo;


public class EnumTest {


/**
* @param args
*/
public static void main(String[] args) {
WeekDay wd=WeekDay.SUN;
System.out.println(wd);

//打印weekday在WeekDay中的角标
  System.out.println(wd.ordinal());
// 获取指定的值  valueOf() 静态方法
     System.out.println(wd.valueOf("MON"));
//  获取所有的值
System.out.println(wd.values().length);
      
}
//创建一个枚举应用 enum类,定义在内部
   public enum WeekDay{
 SUN,MON,TUE,WED,THI,FRI,SAT
}
}
打印:
SUN
0
MON
7


枚举的构造方法:构造方法私有化private
   public enum WeekDay{
 SUN,MON,TUE,WED,THI,FRI,SAT(6)
 //SUN——FRI初始化调用无参构造方法
 public WeekDay(){
 }
 //SAT(6) 调用的是带参数WeekDay(int day)
  public WeekDay(int day){
 }
}
枚举带抽象方法:(变量取值固定,定义抽象意义不大 )


交通灯管理系统讲到抽象方法


 public enum TrafficLamp{
      //new子类的对象,调用父类的构造方法。
      RED(40){
          public TrafficLamp nextLamp() {
              return GREEN ;
          }
      },
      GREEN(60){
          public TrafficLamp nextLamp() {
              return YELLOW ;
          }
      },
      YELLOW(5){
          public TrafficLamp nextLamp() {
              return RED ;
          }
      };
        //定义抽象方法:
      public abstract TrafficLamp nextLamp() ;
       // 定义交通灯的时间,成员变量
      private int time ; 
      private TrafficLamp(int time) {
          this.time = time ; 
      }
  }


5.基本数据类型自动拆箱装箱:
方便操作基本类型值,将其封装成对象,定义了属性和行为,丰富数据操作


左边到右边是封装,右转左则是拆箱,装箱与拆箱是一个相互的过程。
基本类型         封装类型
byte              Byte
short             Short
int               Integer
float             Float
double            Double
public class TestBox {
    public static void main(String[] args) {


        Integer i = 5 ;
// 自动装箱:将基本数据类型int 5自动封装给一个Integer对象
       Integer i = new Integer(5) ;
      
       Integer i = 5; //自动装箱,1.5版本后的写法;
        
        System.out.println(i + 5);
              
        自动拆箱原理:i.intValue()
       
        i=i.intValue()+5  //5是int类型,i是对象封装类型,相加是将i自动转换为int 型 即自动拆箱        
        
        Integer a = 13 ; 
        Integer b = 13 ; 
        System.out.println(a==b); true a 、b指向的是同一个对象
   
    }
}
举例:Integer x = 1; x = x + 1;  经历了什么过程?装箱——>拆箱——>装箱;


享元模式(flyweight):如果有很多很小的对象,我们会经常用到,用的时候该对象的内部状态都没有变化,那么就可以把他变成一个对象


。那些不同的属性把它变成方法的参数(外部状态),那些相同的属性叫内部状态。


6.反射:


反射就是将一个Java类中各个成分映射成想要的Java类,通过反射来获取类的方法属性等信息。
反射实现步骤:
            1.得到Class对象,也就是获得字节码对象(每个类都有对应的字节码对象)
            2.实例对象,获得构造函数,属性,方法。
            3.访问属性、方法、调用构造函数创建该类对象。
 获取Class对象三中方式:
   方式一:Class.forName("com.itheima.Person")// 获取指定字符串类名,加载字节码文件
   方式二:Class clazz=Person.class ;//明确类 每个数据类型都有静态的.class属性,格式:类名.class 。
   方式三:clazz=new Person().getClass();// 对象.getClass()方法,必须有该类对象
   
反射获取成员方法:getMethod()方法获取
   Class clazz=Person.class //获取Class对象 
   Method m=clazz.getMethod(要获取的方法名,类型.class);
          m.invoke()//调用其方法
 package com.itheima.reflect.demo;


import java.lang.reflect.Constructor;
import java.lang.reflect.Method;


public class ReflectDemo4 {


/**
*@throws Exception 
* @hutian
*/
//反射获取成员函数,getMethod
public static void main(String[] args) throws Exception {

getMethodDemo3();

getMethodDemo1();
}
    public static void getMethodDemo() throws Exception{
    // 获取Class对象
    Class clazz=Person.class
     
    Method m=clazz.getMethod("paramMethod", String.class,int.class);  //获取方法
   
    //invoke()表示调用的意思,需要传入对象和参数
    m.invoke("小强", 18);
    }
    
    //获取指定Class类中的所有公共函数。。
    public static void getMethodDemo1() throws Exception{
    // 类名,字符串获取反射信息
    Class clazz=Class.forName("com.itheima.bean.Person");
     
    Method[] methods=clazz.getMethods();  //getMethods()获取的是共有的方法
            methods=clazz.getDeclaredMethods(); //获取本类中所有方法,包括私有。
        
    for(Method m:methods){
    System.out.println(m);
    }
   
    }
}
 
 反射构造方法:Constructor 构造器,getConstructor()获取 
    Class clazz=Class.forName("com.itheima.bean.Person")
    //获取带参数的构造方法
    Constructor ct= clazz.getConstructor(String.class,int.class);
    //对象初始化,使用构造器的newInstance()
    Object obj=ct.newInstance("张三",30);
     
     
 反射成员变量:Field 类代表某个类中的成员变量
     //1.获取Class对象
     Class clazz=Class.forName("com.itheima.bean.Person")
      Object obj=clazz.newInstance();  //初始化
     //fl 对象存储的是Person类country 属性值和它所属的对象
     Field fl = clazz.getField("country"); //getField()获得的public 共有的成员country(国家)
   
     //暴力反射
     Field fl2 = clazz.getDeclaredField("name"); //获取类成员,包括private私有的成员
           fl2.setAccessible(true);
       
 案例展示
 package com.itheima.reflect.demo;


import java.lang.reflect.Field;


public class ReflectPoint {


/**
* @param args
*/

private int x ;
public int y ;
public String str="bahabak" ;
public String str1="blue" ;  
public String str2="balck" ; 
public static void main(String[] args) throws Exception {
ReflectPoint rp=new ReflectPoint();
System.out.println("改变前的值:"+rp);
ChangeValue(rp);
System.out.print("改变后的值:"+rp);


}
public ReflectPoint(String str,String str1,String str2){
super();
this.str=str;
this.str1=str1;
this.str2=str2;
}
public ReflectPoint(){
super();
this.x=x;
this.y=y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public String getstr() {
return str;
}
public void setstr(String str) {
this.str = str;
}
public String getStr1() {
return str1;
}
public void setStr(String str1) {
this.str1 = str1;
}

public String getStr2() {
return str2;
}
public void setStr2(String str2) {
this.str2 = str2;
}

public String toString() {
      return str+ ":" + str1+":"+str2 ; 
 }
 
public static void ChangeValue(Object obj)throws Exception{
// 获取File对象,先获取Class对象,Filed对象得到成员字段信息
Field[] fl = obj.getClass().getFields() ;
for(Field field:fl){
if(field.getType().equals(String.class)){
  if(field.getType()==String.class) {
       
    String old=(String) field.get(obj);
    String newString=old.replace('b', 'a');
    // 保存修改后的数据
       field.set(obj, newString) ;
     
  }
}
}
 
}


}
打印:
改变前的值:bahabak:blue:balck
改变后的值:aahaaak:alue:aalck
       
反射作用:实现框架功能
练习: 写一个小框架,该框架的作用则是根据用户的需求设置不同的集合类型如ArrayList、HashSet等,存入数据。
       通过配置文件config.properties 来完成集合的选择   
 package com.itheima.reflect.demo;


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Collection;
import java.util.Properties;


public class ReflectTest1 {


/**
* @param args
* @throws Exception 
*/
public static void main(String[] args) throws Exception {
// 文件存入数据 FileInputStream

FileInputStream fis=new FileInputStream("config.properties");

Properties pt = new Properties() ;
        //按照行从读取流中属性键值对元素
        pt.load(fis);
        //关闭流
        fis.close();
        
        String className = pt.getProperty("className") ; 
        //不同的集合类型如ArrayList、HashSet,Collection 跟接口,反射创建实体
        Collection cot=(Collection) Class.forName(className).newInstance();
                   cot.add("a");
                   cot.add("haha");
                   cot.add("helloworld");
                   cot.add("love you?");
                   
                   System.out.println(cot.size());
        
}


}


7.代理与类加载器:
代理类:JVM可以在运行时动态生成类的字节码,这种动态生成的往往被用作代理类。
代理机制:每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,
         将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。
举例:各人觉得网上购物,通过某宝购物平台,这个购物平台就像是代理。


代理体现:采用工厂模式和配置文件的方式进行管理,实现日志功能
JVM生成的动态类必须实现一个或多个接口,所以,JVM的动态类只能用作具有相同接口的目标类的代理。
实现AOP功能的封装与配置:
Public class BeanFactory{
Properties props=new Properties();
Public BeanFactory(InputStream ips){
Props.load(ips);
}
}public Object getBean(String name){
String className==props.getProperty(name);//根据名字拿类名
Class clazzName=Class.forName(className);
Object bean=clazz.newInstance();
If(bean instanceof ProxyFactoryBean){
Object proxy=null;
ProxyFactoryBean proxyFactoryBean=( ProxyFactoryBean)bean;
Advice advice=(Advice)Class.forName(props.getProperty(name+”.advice”)).newInstance();//系统功能对象
Object target=class.forName(props.getProperty(name+”.advice”)).newInstance();
//目标对象
proxyFactoryBean.setAdvice(advice);
proxyFactory.setTarget(target);
Object proxy=ProxyFactoryBean(bean).getProxy();
}return null;
}




8.类加载器:
      顾名思义类加载的工具,将类加载到Java虚拟机中。JVM运行将类的字节码文件加载进来。由加载器名称定位和产生类的字节码依据返


回给JVM。


1.过程:
Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,


并转换成 java.lang.Class类的一个实例。


2.类加载器分类:一般由系统提供,另一类由开发人员自己定义类加载器


引导加载器(Bootstrap) :它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自java.lang.ClassLoader。
扩展加载器(ExtClassLoader 的实例):加载Java扩展库
系统加载器(AppClassLoader的实例):根据Java类ClassPath路径来加载Java类。
自定义加载器:系统已经定义了一些类加载器,为了达到特殊功能,开发者自己定义一些类加载器
自定义的类加载器要继承ClassLoader。


3.类加载器的委托机制: 每个类加载器加载类时,先委托给其上级父类加载器,如果没有,直到BootStrap(祖宗类)加载器,当*父类加载


器没有加载到类时,再尝试自己加载,还加载不到就抛ClassNotFoundException,不会再去找下一级了。


基本上所有的类加载器都是有一个父类加载器,都是java.lang.ClassLoader 类的一个实例


4.相关方法:
getClassLoader() 返回该类的类加载器。返回类型 ClassLoader  
getParent()  返回该类加载器的父类加载器。 
loadClass(String name)  加载名称为 name的类,返回的结果是 java.lang.Class类的实例。 
findClass(String name)  查找名称为 name的类,返回的结果是 java.lang.Class类的实例。 
findLoadedClass(String name)  查找名称为 name的已经被加载过的类,返回的结果是 java.lang.Class类的实例。 
defineClass(String name, byte[] b, int off, int len)  把字节数组 b中的内容转换成 Java 类,返回的结果是 java.lang.Class类的实


例。这个方法被声明为 final的。
resolveClass(Class<?> c)  链接指定的 Java 类。


package com.itheima.proxy;


public class ProxyDemo {


/**
* @param args
*/
public static void main(String[] args) {
   ClassLoader loader = ProxyDemo.class.getClassLoader();  //通过  getClassLoader() 方法就可以获取到定义此类加载器


的引用
   while (loader != null) {              
    System.out.println(loader.toString());             
    loader = loader.getParent();   //通过递归调用 getParent() 方法来输出全部的父类加载器       
   
   } 


}


}
 打印结果:
sun.misc.Launcher$AppClassLoader@fb56b1
sun.misc.Launcher$ExtClassLoader@f8968f






 ---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、
<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------