I am trying to use a vector to hold my classes. These classes inherit methods from another class and have their own methods as well. What I am having trouble with is using the vector with objects to call the methods from the class within the object. I thought it would be something like:
public static void vSort(Vector<Object> vector) {
vector[0].generate();
}
with generate being a custom method i created with the student class within the object.
A better example
public class Method {
protected String name;
public void method() {
// some code
}
}
public class Student extends Method {
protected String last;
public void setUp() {
// some code
}
}
public class Main {
public static void main(String[] args)
{
Vector<Object> vector = new Vector<Object>();
Student stu = new Student(); // pretend this generates something
vector.add(stu);
}
The problem i am running into is there are many classes like student that build on Method. If i cant use Object that is fine with me but i need to access the code within the Method class.
Java doesn't have operator overloads. So the syntax is:
vector.get(0).generate();
However, this won't work at all in your case, because you have a Vector<Object>, and an Object doesn't have a generate method.
[Tangential note: vector is de facto deprecated; you should probably use ArrayList instead.]
you should use vector.get(0) to retrieve your object.
Also note, that Object does not declare generate() - so you are going to need to cast or specify your object as the generic type.
When you have a Vector<Object>, all the retrieval methods return Object, so you can't call subclass methods unless you explicitly downcast. You should use Vector<YourClass> instead, so that the references you get out of the vector are of type YourClass and you don't have to downcast them.
Related
I have following two classes
public abstract class A {
public String p1;
public String p2;
// Includes getters/setters
}
public class B extends A {
public String p3;
public String p4;
// Some implementation to populate base class attributes
// Includes getters/setters
}
public static void main(String[] args) {
// Initializing and populating parameters for B
System.out.println(B.getP1());
System.out.println(B.getP2());
}
How can print all the elements of the base class B without invoking individual getters for the attributes in main. Since there is a possibility that in future class A will have additional attribute that will require using getter method again in main for that attribute. All I want is to print all the attributes from the Base class only.
You should be able to do that by iterating over the attributes of the base class using reflection.
import java.lang.reflect.Field;
class B {private String p1="1"; private String p2="2";}
class A extends B {private String p3="3"; private String p4="4";}
public class Scratch {
static void showFields(Class clazz, Object obj) throws Exception {
for(Field f:clazz.getDeclaredFields()) {
f.setAccessible(true);
System.out.println("Field "+f.getName()+" had value "+f.get(obj));
}
}
public static void main(String[] args) throws Exception {
System.out.println("Fields defined in parent: ");
showFields(B.class, new A());
System.out.println("Fields defined in child");
showFields(A.class, new A());
}
}
So I tested this and it works for me--but I run java 8. I just did a little looking around and it looks like they might be removing the ability to setAccessable in a later version (Or maybe just from the core java classes..
need to experement).
The other possibility is to read from public methods instead of members. Use getDeclaredMethods() instead of getDeclaredFields() and your array will have to be an array of Method. Instead of calling .get(obj) call .invoke(obj). Make sure that the method didn't take any parameters (Getters won't take parameters), there is a parameter count in the Method object that will tell you if it takes parameters. If you start with this code don't forget to add getters to A and B.
As long as the getter methods are public, this should work. At least this code should give you some place to start.
Please let me know how this works for you, I will soon have to migrate a lot of code forward and it's going to be a lot harder if this doesn't work any more.
I have some code that I need to reuse in several Java apps. That code implements a GUI which in turn needs to access some static variables and methods from the calling class. Those variables and methods are always called the same in all of the apps. Is there a generic way to obtain a handle to the calling class in Java so the code for "someGUI" class can remain untouched and in fact come from the same source file for all the different apps?
Minimal working example:
import javax.swing.*;
class test {
static int variable = 123;
public static void main(String[] args) {
someGUI sg = new someGUI();
sg.setVisible(true);
}
}
class someGUI extends JFrame {
public someGUI() {
System.out.println(String.format("test.variable = %d", test.variable));
}
}
How can I "generify" the reference to "test" in test.variable to always just refer to the calling class? It's not the "super" class, at least using super.variable doesn't work.
Firstly I would advise against this approach since there are only brittle ways to implement it. You should parameterize SomeGUI with a parameter containing the values you need instead.
However, it is possible to do what you ask by examining the thread's stack trace and using reflection to access the static fields by name. For example like this:
class Test {
static int variable = 123;
public static void main(String[] args) throws Exception {
SomeGUI sg = new SomeGUI();
}
static class SomeGUI extends JFrame {
public SomeGUI() throws Exception {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
// stackTrace[0] is getStackTrace(), stackTrace[1] is SomeGUI(),
// stackTrace[2] is the point where our object is constructed.
StackTraceElement callingStackTraceElement = stackTrace[2];
String className = callingStackTraceElement.getClassName();
Class<?> c = Class.forName(className);
Field declaredField = c.getDeclaredField("variable");
Object value = declaredField.get(null);
System.out.println(String.format("test.variable = %d", value));
}
}
}
This will print test.variable = 123.
Obviously this is sensitive to renaming of the variables. It is also sensitive to dynamic proxies.
Also, it should be noted that you need to do this in the constructor. If you try to do this kind of lookup in other methods you can not find out how the instance was created.
There is no inheritance between somGUI and test,
Actual inheritance is there between someGUI and JFrame.
If you use super(), JVM tries to find 'variable' in JFrame, that is not what you wanted.
Use static methods setters & getters to access the 'variable' instead of direct accessing them.
I am learning of interface in java while i access it in my sub class main method i can access in three way what are the difference of those am learner could some one help on this
public interface interfa
{
void educationloan();
abstract void homeloan();
static int i = 10;;
}
public class testinter implements interfa {
public static void main(String args[])
{
System.out.println("Sub class access a interface by implement");
testinter t = new testinter();
t.miniloan();
t.educationloan();
t.homeloan();
System.out.println("Super class access a only interface in sub class");
interfa a = new testinter();
a.educationloan();
//a.miniloan();
a.homeloan();
System.out.println("Annomys class access a only interface in sub class");
interfa xx = new interfa() {
#Override
public void homeloan() {
}
#Override
public void educationloan() {
// TODO Auto-generated method stub
}
};
xx.educationloan();
xx.homeloan();
}
}
Here my question comes which one can use in which situation and what are the difference???
First thing you will get a compile time error big time as you haven't implemented the interface methods in the child class.
testinter t = new testinter();
t.miniloan();
t.educationloan(); // these methods should be initialized
t.homeloan();
Now regarding your interface implementation ways:
testinter t = new testinter();
t is an instance of a child class & can be used like a regular class object.
interfa a = new testinter();
The upside of using this approach is say you have used the reference a n times in your code & in future you want to change the implementation of your interface to interfa a = new AnotherTestinter(); All you have to do is change the implementation the reference will not be changed. This is loose coupling otherwise you have to change the reference a everywhere in the code. This approach is always known as Programming to an interface.
Using anonymous class
interfa xx = new interfa() {
#Override
public void homeloan() {
}
#Override
public void educationloan() {
// TODO Auto-generated method stub
}
};
Anonymous classes enable you to make your code more concise. They enable you to declare and instantiate a class at the same time. They are like local classes except that they do not have a name. Use them if you need to use a local class only once.
So doing this interfa xx = new interfa() { helps you define your methods educationloan() homeloan() at the same place.
t itselft is a instance of a child class. it can be used normally like other class objects
t is a instance of the interfa. Here t can be used in both cases where either the child or the parent class is needed.
in this implementation you have to implement the methods of the interface in your own way. You can implement different things here instead of using the default implementation.
N.B. I overlooked one thing, you will get a compiler error as you haven't implemented the methods of interfa in the child class
I'm trying to reduce some code duplication. Currently i got two methods that are almost identical, the major difference being calling two separate methods within them.
Below is basically what i wanna do:
private void combinedMethod(StandardClass sc, MyClass mc)
{
Method m = null;
if(mc instanceof MySubClass1)
m = sc.RelevantFor1();
if(mc instanceof MySubClass2)
m = sc.RelevantFor2();
m(mc.getA(), mc.getB());
}
I've tested (and it works) this using reflection. But is there a better way of doing it? I read somewhere that reflection is slow and only to be used as a last resort. Is it in this case?
Also in this case the StandardClass is a standard class in the java api. The Class I send in is of my own making.
It isn't clear how exactly those methods look like, or what they are doing, but it seems like a perfect polymorphism case. You can create a method in super class - MyClass I suppose in this case. And override those methods in your subclasses.
Now, when you call that method on MyClass reference, appropriate subclass method will be called based on actual instance. Now invoke whatever method you want to invoke in respective overridden methods.
Somewhere along the lines of:
class MyClass {
public void method(StandardClass sc) { }
}
class MySubClass1 extends MyClass {
public void method(StandardClass sc) {
sc.method(getA(), getB());
}
}
class MySubClass2 extends MyClass {
public void method(StandardClass sc) {
sc.anotherMethod(getA(), getB());
}
}
And then your combinedMethod looks like:
private void combinedMethod(StandardClass sc, MyClass c) {
c.method(sc);
}
Is it posible in java?
void aaa(){}
ArrayList<Method> list = new ArrayList<Method>();
list.add(aaa);
If it isn't, how i can realize collection of methods (functions).
I want to get some method by ID.
You can do something like:
interface VoidFunction {
void evaluate();
}
...
List<VoidFunction> list = new ArrayList<>();
VoidFunction aaa = new VoidFunction() {
#Override
public void evaluate() {
aaa();
}
}
list.add(aaa);
In Java 8 this should be much easier and nicer:
List<Consumer<Void>> list = new ArrayList<>();
Consumer<Void> aaa = () -> {...};
list.add(aaa);
(I believe I have the syntax right)
If you already have the aaa method defined as a regular method, you'll be able to do something like:
list.add(MyClass::aaa);
You need to use reflection to get the Method, e.g.
this.getClass().getMethod("aaa")
Alternatively, if you don't need to access methods defined on a class, you can use Callables.
ArrayList<Callable> list = new ArrayList<Callable>();
list.add(new Callable() {
public String call() {
return "asdf";
}
});
I believe you can do it, but you need to use reflection to get the methods from a class/object. Maybe this links helps: http://tutorials.jenkov.com/java-reflection/methods.html
The way you have done it does not work.
You can call following method of Class
public Method[] getMethods() throws SecurityException
Returns an array containing Method objects reflecting all the public member methods of the class or interface represented by this Class object, including those declared by the class or interface and those inherited from superclasses and superinterfaces.
public Method[] getDeclaredMethods() throws SecurityException
Returns an array of Method objects reflecting all the methods declared by the class or interface represented by this Class object. This includes public, protected, default (package) access, and private methods, but excludes inherited methods.
Read more here
Cheers !!