I have a class with name "ConstituentSet". it has one method namely "getNucleusInConstSet()" which the output will be from "Proposition" class . The new Class "Proposition" have another method namely "getProperty()". I want to know what is the Propertry of my "Proposition Nucleus" in class "ConstituentSet". but i do not know how can i do that.
I wrote as follow but It does not work. (ConstituentSet.getNucleusInConstSet()).getProperty())
public class ConstituentSet{
// Constructor
private Proposition nucleusInConstSet;
public Proposition getNucleusInConstSet() {
return nucleusInConstSet;
}
}
public class Proposition{
//Constructor
private Property property;
public Property getProperty() {
return this.type;
}
}
You have:
(ConstituentSet.getNucleusInConstSet()).getProperty()
But you need to call an instance of ConstituentSet
e.g.
ConstituentSet cs = new ConstituentSet();
cs.getNucleusInConstSet().getProperty();
Note that this idiom (chained method calls) can be a pain. If one of your methods returns null, it's difficult to understand which one it is (without using a debugger). Note also that invocations of the form a().b().c().d() are a subtle form of broken encapsulation (a reveals that it has a b, that reveals it has a c etc.)
if you type ((ConstituentSet.getNucleusInConstSet()).getProperty()) you are attempting to call a static method of ConstituentSet.
You need to instantiate it and then call on that object.
ConstituentSet anInstanceOf = new ConstituentSet();
anInstanceOf.getNucleusInConstSet()).getProperty());
This won't work:
ConstituentSet.getNucleusInConstSet().getProperty();
Because the getNucleusInConstSet() method is not static. You have to use an instance of ConstituentSet, something like this:
ConstituentSet cs = new ConstituentSet();
cs.getNucleusInConstSet().getProperty();
Of course, you have to make sure that nucleusInConstSet is not null, or you'll get a NullPointerException. Initialize its value in ConstituentSet's constructor or set it using setNucleusInConstSet().
Alternatively, you could make getNucleusInConstSet() static, but I don't think that's the right thing to do in this case (but we don't have enough information about the problem to say so).
Related
Simplified demo code to show my problem.
class Base {
public String toString() { return "Base"; }
};
class A extends Base {
public String toString() { return "A"; }
};
class Test {
public void test1() {
A a = new A();
Base b = (Base)a; // cast is fine, but b is the same instance as a
System.out.println(b.toString()); // want "Base", but get "A"
}
private String testB(Base b) {
return b.toString(); // this should return "Base"
}
public void test2() {
System.out.println( testB(new A()) ); // want "Base", but get "A"
}
};
I tried the cast approach (test1) , and the helper method (test2).
Up to now, I found to need a copy constructor for Base to create a real Base object.
Is there a method that does not need a duplicate object?
Some background info:
I get an instance of A, and I know its base class has a nice method, which I'd like to use instead of the overwritten version. I'd prefer to neither modify class A nor B (although a copy c'tor were a good enhancement anyway ;) )
From class A directly, you can use super.toString(); to execute toString() on Base.
However, from outside class A, you can't call the superclass implementation in this way, doing so would break encapsulation. If you want to expose the superclass implementation then you still can, but you have to provide a separate method on A that exposes it directly.
Even using a trivial reflection based approach, you still won't be able to access it:
If the underlying method is an instance method, it is invoked using dynamic method lookup
System.out.println(Base.class.getMethod("toString", null).invoke(new A(), null)); //Prints "A"
...and using MethodHandles.lookup().findSpecial won't work either from outside the child class, as that has to be invoked where you have private access (otherwise you'll just get an IllegalAccessException.)
I concede that there may well be some weird and wonderful way of doing it directly in Java that I haven't thought of without bytecode manipulation, but suffice to say even if you can do it that way, you certainly shouldn't for anything but a quirky technical demonstration.
You need to create the B instance(copy constructor), if you are using the A instance you will always get "A" no matter if you cast it or no.
Using ByteBuddy, can I implement one instance method by calling another and transforming the result?
For instance (toy example):
public abstract class Foo {
public String bar() {
return "bar";
}
public abstract int baz();
}
Given the above, can I implement baz such that it calls bar() and returns the length of the returned string? I.e., as if it were:
public int baz() {
return bar().length();
}
Naively, I tried the following:
Method bar = Foo.class.getDeclaredMethod("bar");
Method baz = Foo.class.getDeclaredMethod("baz");
Method length = String.class.getDeclaredMethod("length");
Foo foo = new ByteBuddy()
.subclass(Foo.class)
.method(ElementMatchers.is(baz))
.intercept(
MethodCall.invoke(bar) // call bar()...
.andThen(MethodCall.invoke(length)) // ... .length()?
).make()
.load(Foo.class.getClassLoader())
.getLoaded()
.newInstance();
System.out.println(foo.baz());
However, it looks like I was wrong in thinking andThen() is invoked on the return value of the first invocation; it looks like it's invoked on the generated instance.
Exception in thread "main" java.lang.IllegalStateException:
Cannot invoke public int java.lang.String.length() on class Foo$ByteBuddy$sVgjXXp9
at net.bytebuddy.implementation.MethodCall$MethodInvoker$ForContextualInvocation
.invoke(MethodCall.java:1667)
I also tried an interceptor:
class BazInterceptor {
public static int barLength(#This Foo foo) {
String bar = foo.bar();
return bar.length();
}
}
with:
Foo foo = new ByteBuddy()
.subclass(Foo.class)
.method(ElementMatchers.is(baz))
.intercept(MethodDelegation.to(new BazInterceptor()))
// ...etc.
This ran, but produced the nonsensical result 870698190, and setting breakpoints and/or adding print statements in barLength() suggested it's never getting called; so clearly I'm not understanding interceptors or #This properly, either.
How can I get ByteBuddy to invoke one method and then invoke another on its return value?
Per k5_'s answer: BazInterceptor works if either:
we delegate to new BazInterceptor(), as above, but make barLength() an instance method, or:
we leave barLength() a class method, but delegate to BazInterceptor.class instead of to an instance.
I suspect the 870698190 was delegating to hashCode() of the BazInterceptor instance, though I didn't actually check.
There is not currently a good way in Byte Buddy but this would be an easy feature to add. You can track the progress on GitHub. I will add it once I find some time.
If you want to implement such chained calls today, you can implement them in Java code and inline this code using the Advice component. Alternatively, you can write the byte code more explicitly by creating your own ByteCodeAppender based on MethodInvocation instances where you have to load the arguments manually however.
You use an instance as interceptor, that means instance methods are prefered (maybe static method are not accepted at all). There is an instance method that matches the signature of your int baz() method, it is int hashCode(). The number you are getting is the hashcode of the new BazInterceptor() instance.
Options i am aware of:
Remove static from barLength that way it will actually be used for interception.
Add the class as interceptor .intercept(MethodDelegation.to(BazInterceptor.class))
I would prefer the second option as you are not using any fields/state of the BazInterceptor instance.
I am a beginner in Java. I have two packages in my current project. Each of the packages have two classes called the "packageClassOne" and "packageClassTwo".
The packageClassTwo has a constructor and other public methods.
I want to call the PackageClassTwo from an if statment located in the PackageClassOne. My code looks something like this
packageClassOne:
public class packageClassOne {
public void selectComponent(boolen) {
if(/* check condition*) {
packageClassTwo value = new packageClassTwo();
}
}
}
packageClassTwo:
public class packageClassTwo {
public packageClassTwo(String name){ //Constructor
int length = name.length();
}
public String CreateWord(){
/*functionality ofthis method*/
}
public String CreateSentence(){
/*functionality ofthis method*/
}
}
The problem is that everytime I call the packageClassTwo from my packageClassOne it tries to call the constructor instead of calling the class itself. I want to call the entire packageClassTwo instead of just the constructor.
Can somebody help me please? Thank you in advance for your help
Since Java is an object oriented language, you have to have a mindset of dealing with instances that are realizations of the classes you defined. These are the objects.
So if you want to call a method from packageClassTwo class, you first create an object of packageClassTwo. You seem to be trying to do just this. Once you have the object, you can call its methods. For example
//Instantiate an object by calling the constructor
packageClassTwo object = new packageClassTwo(string);
//Now call its methods
String val = object.CreateWord()
There is no such thing as "calling a class". You call methods of objects of a class.
Occasionally, there might be a well founded need to call methods of a class without initializing objects. Look into static methods and classes for further reading.
If you want to call all methods of packageClassTwo you have to do it explicitly
packageClassTwo pct = new packageClassTwo("");
pct.CreateWord();
pct.CreateSentence();
If you allways want the 2 methods to be called when you create a new packageClassTwo object, than you can just add the calls to the constructor
public packageClassTwo(String name) {
int length = name.length();
pct.CreateWord();
pct.CreateSentence();
}
Edit:
Note that in the second case, if you end up only calling the 2 methods from inside the constructor, it is better to make them private.
As a sidenote, it is a general convention in java to have class names start with a upper case letter : PackageClassTwo not packageClassTwo, and method names to start with lower case createWord not CreateWord. This wll make your code more readable.
If you want to call all the methods from the packageClassTwo, call them from the packageClassTwo constructor
public packageClassTwo(String name)
{
int length = name.length();
CreateWorld();
CreateSentence();
}
I don't think your code will run without compiling errors.because you did not declare the constructor packageClassTwo().
I have the following, stripped-down Java code:
// Class, in it's own file
import java.util.*;
public class Superclass {
protected List<Subclass> instances = new ArrayList<>();
public class Subclass extends Superclass {
private int someField;
public Subclass(int someValue) {
this.someField = someValue;
updateSuperclass();
}
private void updateSuperclass() {
super.instances.add(this);
}
}
}
// Implementation, somewhere else, everything has been imported properly
Superclass big = new Superclass();
Subclass little1 = big.new Subclass(1);
Subclass little2 = big.new Subclass(2);
Subclass little3 = big.new Subclass(3);
I want to implement a method in Superclass to do something with all the Subclasses. When a Subclass is created, it should add itself to a list in Superclass, but whenever I try to loop through that list in Superclass, it says the size is 1. The first element in the list (instances.get(0)) just spits out a String with all the proper information, but not in object form, and not separately. It's like every time I go to add to the list, it gets appended to the first (or zeroeth) element in String form.
How can I solve this so I can maintain an ArrayList of Subclasses to later loop over and run methods from? I'm definitely a beginner at Java, which doesn't help my case.
If all you need is a count then I suggest a static value that is updated in the constructor of the parent class.
private static int instanceCount = 0;
public Constructor() {
instanceCount++;
}
If you absolutely need every instance in a list so you can do something with them then I recommend you strongly re-consider your design.
You can always create a utility class that will let you maintain the list of objects to run processes on. It's more "Object Oriented" that way. You can also create one class that has all of the operations and then a simpler bean class that has only the data values.
But, if you insist, you can still use the same technique.
private static List<SuperClass> list = new LinkedList<SuperClass>;
public Constructor() {
list.add(this)
}
Each instance gets its own copy of your superclass's variables.
What you want to do is make the variable "static" by putting the static keyword before it. You probably don't even need the superclass accomplish what you're trying to do.
class Super {
public void anotherMethod(String s) {
retValue(s)
}
public String retValue(String s) {
return "Super " + s;
}
}
class Sub extends Super {
public void anotherMethod(String s) {
retValue(s)
}
public String retValue(String s) {
return "Sub " + s;
}
}
if suppose in main,
Super s = new Sub();
s.anotherMethod("Test");
Output will be, Sub Test
Can you anyone help me in telling how to get output Super Test with the given sequences in main.
And let me explain why I want this, say I have a class which has method test() and it can be overriden by sub classes, in some cases I want the overriden test() and in some cases I want the test() of super class itself, there are many ways to do this, best suggestions will be helpful.
Why would you ever want to do that ??
The whole point of polymorphism is to call the right method without the need to know which kind of instance you've got ...
Whenever I find myself asking (or being asked) a question like this, I know, categorically, that I have made a mistake in my design and/or my object definitions. Go back to your object hierarchy and check, double-check and triple-check that every inheritance relationship represents an "IS-A", and not a "HAS-A" or something even weaker.
And let me explain why I want this,
say I have a class which has method
test() and it's can be overriden by
sub classes, some cases I want the
overriden test() and in some cases
test() of super class itself, there
are many ways to do this, it will be
helpful if anyone can be best
solution.
If your subclass overrides test(), then it overrides test() - this is the whole point of object inheritance. You just call methods on the object, which are dynamically resolved to the appropriate implementation based on the object's runtime class. That's the beauty of polymorphic typing, in fact, the caller doesn't have to know about any of this at all, and the subclasses determine how their behaviour differs from the superclass.
If you sometimes want it to act as its superclass method and sometimes want it to act as its subclass method, then you need to provide the context required to do this. You could either define two test-type methods; one which is never overridden and so always returns the superclass' behaviour (you can even mark the definition with final to ensure it's not overridden), and your normal one which is overridden as appropriate by the subclasses.
Alternatively, if there is some contextual information available, you can let the subclasses decide how to handle this; their implementation(s) could check some proeprty, for example, and based on that decide whether to call super.test() or proceed with their own overridden implementation.
Which one you choose depends on conceptually whether your main method (i.e. the caller), or the (sub)class objects themselves, are going to be in the best position to judge whether the superclass' method should be called or not.
But in no case can you override a method and expect it to magically sometimes not be overridden.
You would have to go the route of:
Super s = new Super();
s.anotherMethod("Test");
...but that will defeat the purpose of inheritance if you also need whatever Sub's got. You could hack it like below but this seems an unelegant way to do it.
class Sub extends Super {
public String anotherMethod( String s, boolean bSuper ) {
if( bSuper )
return super.retValue(s);
else
return retValue(s);
}
public String retValue(String s) {
return "Sub " + s;
}
}
From class Sub you can call super.anotherMethod("bla"), but you cannot access the method of the superclass in your main method - that would be against the whole idea of using subclasses.
The runtime type of s is Sub, so you're only ever calling methods on that class.
Whilst I agree with the other posters that this is not the best idea in the world, I believe it could be done with a little bit of tinkering.
If your child class was defined as:
class Sub extends Super {
public void anotherMethod(String s) {
retValue(s)
}
public void yetAnotherMethodString s) {
super.retValue(s)
}
public String retValue(String s) {
return "Sub " + s;
}
}
and then call this new method in your main you would be able to print out "Super Test".
Doesn't seem like a very good plan tho. If you want access to parent functionality from a child class then don't override your parent method, just write a new one!
I'm hesistant to post this as an answer, since the question is quite horrible - but static methods would do roughly what the OP seems to want. Specifically, they are resolved on the compile-time declared class of the variable, not on the class of the instance held within that variable at runtime.
So modifying the original example:
class Super {
public static void staticMethod(String s) {
System.out.println("Super " + s);
}
}
class Sub extends Super {
public static void staticMethod(String s) {
System.out.println("Sub " + s);
}
}
public static void main(String[] args) {
Super s = new Sub();
s.staticMethod("Test");
}
then main() will print out "Super test".
But still don't do this until you understand why you want to, and you recognise that you are introducing subclasses and then gratuitously working around the point of them being there. Most IDEs for example will flag the above example with lots of warnings, saying that you shouldn't call static methods on instance variables (i.e. prefer Super.staticMethod("Test") instead of s.staticMethod("Test")), for exactly this reason.
You cannot modify Sub or Super directly? If you could control what instance of Sub is used you could do something like:
Super sub = new Sub() {
#Override
public String retValue() {
// re-implement Super.retValue()
}
};
otherObject.use(sub);
Of course this requires you to have or be able to reproduce the source code of Super.retValue() and for this method not to use anything you can't access from an anonymous child. If the API is this badly designed though, you might do well to think about changing it out for something else.
Can you anyone help me in telling how
to get output "Super Test" with the
given sequences in main.
Don't overwrite anotherMethod() and retValue() in Sub in the first place.
In Sub.anotherMethod(), return super.retValue(s) instead of retValue(s).