Указатели и виртуальные функции в Java
В настоящее время в Интернете можно найти множество статей как о перспективности платформы Java, так и об её ограниченности. Многих программистов, только присматривающихся к Яве, могут отпугнуть частые заявления, типа: «низкое быстродействие», «отсутствие указателей» и т.д.
На быстродействии я останавливаться не буду. По этой теме можно найти множество статей, например эту. В этой статье я попытаюсь развеять мнение, что в Java отсутствуют указатели. Да, они там действительно отсутствуют в том виде, в котором их можно увидеть в C/C++. Но не даром же все сложные типы в Java называются ссылочными. Можно рассмотреть пример на C. Эта программа меняет местами значения переменных x и y. Могут быть и другие ситуации, где результат должен возвращаться через параметры функции. Но это самый простейший, и, по-моему, самый доходчивый пример.
#include
void change(int *a, int *b)
{
int c=*a;
*a=*b;
*b=c;
}
int main()
{
int x=2, y=3;
printf("%d %d\n", x, y);
change(&x;, &y;);
printf("%d %d\n", x, y);
return 0;
}
Результат работы программы будет выглядеть следующим образом:
2 3
3 2
В Java с простыми типами нельзя сделать это же самое. Но кто нам мешает написать класс-оболочку для простого типа? В общем, рассмотрим аналогичный пример на Java.
Сначала опишем класс-оболочку для типа int:
package ptrtest;
public class IntPtr
{
public int value;
public IntPtr(int a)
{
value=a;
}
}
Затем, используем этот класс в программе:
package ptrtest;
public class Main
{
public void change(IntPtr x,IntPtr y)
{
int z=x.value;
x.value=y.value;
y.value=z;
}
public static void main(String[] args)
{
Main m=new Main();
IntPtr a=new IntPtr(2);
IntPtr b=new IntPtr(3);
System.out.print(a.value);
System.out.print(' ');
System.out.println(b.value);
m.change(a, b);
System.out.print(a.value);
System.out.print(' ');
System.out.println(b.value);
}
}
Результат будет таким же:
2 3
3 2
Недостатком использования такого вида «указателей» может быть только «лишняя писанина», которой нет в С. Но при наличии таких сред, как NetBeans или Eclipse (и некоторых коммерческих), с их развитыми суфлёрами кода, я думаю, наличие «лишнего» кода не является серьёзной проблемой.
Далее можно отметить наличие в Яве только виртуальных функций. При этом не нужно писать перед функцией слово virtual. Да его и нет в языке. Рассмотрим пример:
package virtualfunctest;
// суперкласс
public class Parent
{
protected void f1()
{
System.out.println("Parent class");
}
public void f2()
{
f1();
}
}
package virtualfunctest;
// производный класс
public class Child extends Parent
{
protected void f1()
{
System.out.println("Child class");
}
}
// использование функций
package virtualfunctest;
public class Main
{
public static void main(String[] args)
{
Parent obj;
obj=new Parent();
obj.f2();
obj=new Child();
obj.f2();
}
}
Таким образом, можно увидеть, что язык Java всё же имеет указатели (об этом, кстати, разработчики из Sun Microsystems неоднократно говорили). Главное – это подход к ним. Я не думаю, что в этой статье я показал что-то новое людям, уже работавшим с этим языком. Но думаю, что для новичков эта статься будет хоть чем-то полезна.
А вообще, всё, чего не хватает в языке Ява можно реализовать с помощью JNI. Хотя в данный момент его вполне можно назвать самодостаточным языком.